Java容器

Posted noperx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java容器相关的知识,希望对你有一定的参考价值。

一,list集合排序

对于自定义数据类型,排序可以用Collections集合工具类中的sort()方法,

而要想使用sort()方法则必须实现Comparable接口然后重写里面的compareTo方法或单独一个类实现Comparactor接口重写里面的compare方法

String类型已经实现了Comparable接口

1,实现Comparable接口

public class Teacher implements Comparable<Teacher> 
    String name;
    int age;

    public Teacher(String name, int age) 
        super();
        this.name = name;
        this.age = age;
    

    @Override
    public String toString() 
        return "Teacher [name=" + name + ", age=" + age + "]";
    

    @Override
    public int compareTo(Teacher t) 
        if (age > t.age) 
            return 1;
        
        if (age < t.age) 
            return -1;
        
        if (age == t.age) 
            return name.compareTo(t.name);// 如果age相等则用name排序
        
        return age;
    

 

2,实现Comparactor接口

 

public class Teacher2
    String name;
    int age;

    public Teacher2(String name, int age) 
        super();
        this.name = name;
        this.age = age;
    

    @Override
    public String toString() 
        return "Teacher [name=" + name + ", age=" + age + "]";
        

 

public class AgeAndNameSort implements Comparator<Teacher2>

    @Override
    public int compare(Teacher2 t1, Teacher2 t2) 
        if (t1.age > t2.age) 
            return 1;
        
        if (t1.age < t2.age) 
            return -1;
        
        if (t1.age == t2.age) 
            return t1.name.compareTo(t2.name);// 如果age相等则用name排序
        
        return t1.age;
    

测试方法

void test6()
        Teacher teacher1 = new Teacher("jack", 23);
        Teacher teacher2 = new Teacher("mary", 25);
        Teacher teacher3 = new Teacher("Tom", 25);
        Teacher teacher4 = new Teacher("Alice", 13);
        List<Teacher> list = new ArrayList<>();
        list.add(teacher1);
        list.add(teacher2);
        list.add(teacher3);
        list.add(teacher4);
        list.add(teacher2);
        Collections.sort(list);
        for (Teacher teacher : list) 
            System.out.println(teacher);
        
    
    
    void test7()
        Teacher2 teacher1 = new Teacher2("jack", 23);
        Teacher2 teacher2 = new Teacher2("mary", 25);
        Teacher2 teacher3 = new Teacher2("Tom", 25);
        Teacher2 teacher4 = new Teacher2("Alice", 13);
        AgeAndNameSort ageAndNameSort = new AgeAndNameSort();
        List<Teacher2> list = new ArrayList<>();
        list.add(teacher1);
        list.add(teacher2);
        list.add(teacher3);
        list.add(teacher4);
        list.add(teacher2);
        Collections.sort(list, ageAndNameSort);
        for (Teacher2 teacher : list) 
            System.out.println(teacher);
        
    

测试结果

Teacher [name=Alice, age=13]
Teacher [name=jack, age=23]
Teacher [name=Tom, age=25]
Teacher [name=mary, age=25]
Teacher [name=mary, age=25]

 

3,使用细节

void test3()
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(11);
        list.add(111);
        
        //列表转换为数组
        Integer[] ls1 = list.toArray(new Integer[2]);
        //Integer[] ls2 = (Integer[]) list.toArray();//cannot be cast to [Ljava.lang.Integer;
        Object[] ls3 = list.toArray();
        
        System.out.println(ls1);
        //System.out.println(ls4);
        System.out.println(ls3);
    
    
    void test4()
        Integer[] in = 33, 44, 55;
        //array 转换为list
        List<Integer> list = Arrays.asList(in);//先转换为list 这个list为只读 没有add方法
        List<Integer> arrayList = new ArrayList<>();
        arrayList.addAll(list);
    
    
    void test5()
        //并发修改异常 迭代器相当于集合的副本,当迭代器和集合不一样时(元素个数不同等等)就会报错
        //at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
        List<String> lt = new ArrayList<String>();
        
        lt.add("java");
        lt.add("python");
        lt.add("php");
        
//        Iterator<String> it = lt.iterator();
//        while(it.hasNext())
//            if(it.next().equals("java"))
//                lt.add("C++");
//            
//            System.out.println(it.next());//报错Exception in thread "main" java.util.NoSuchElementException
//        

 

 

二,set集合

HashSet集合可以去重,但对于自定义数据类型必须重写equals方法和hashCode方法

当你把对象加入到HashSet时,它会使用对象的hashCode值判断对象加入的位置。但是同时也会与其他已经加入的对象的hashCode做对比,如果没有相符的hashCode,HashSet就会假设新对象没有重复。也就是说,如果hashcode时相异的,则HashSet会假设对象不可能是相同的。但有相同hashCode()的对象也不一定相等,所以如果HashCode()找到相同hashcode的两个对象:金加入的对象本来就存在的,它会调用其中一个的equals()来检查hashcode相等的对象是否真的相等。

TreeSet不仅可以去重还可以排序,但排序条件和list集合一样,必须实现Comparable接口或Comparactor接口

1,HashSet重写equals方法和hashCode方法

public class Student 
    String name;
    int age;

    public Student(String name, int age) 
        this.name = name;
        this.age = age;
    

    public void method1() 

    

    @Override
    public int hashCode() 
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    

    @Override
    public boolean equals(Object obj) 
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (age != other.age)
            return false;
        if (name == null) 
            if (other.name != null)
                return false;
         else if (!name.equals(other.name))
            return false;
        return true;
    

    @Override
    public String toString() 
        return "Student [name=" + name + ", age=" + age + "]";
    

 

测试类

public class HashSetTest 

    public static void main(String[] args) 
        //创建set集合
        Set<Student> s1 = new HashSet<>();
        
        //创建学生对象
        Student t1 = new Student("xiaoming", 21);
        Student t2 = new Student("xiaojun", 20);
        Student t3 = new Student("xiaoming",21);
        
        //添加学生对象
        s1.add(t1);
        s1.add(t2);
        s1.add(t3);
        
        //遍历学生对象
        for (Student student : s1) 
            System.out.println(student);
        
        
        /*
         * 未实现重写hashCode和equals方法前
         * Student [name=xiaoming, age=21]
         * Student [name=xiaoming, age=21]
         * Student [name=xiaojun, age=20]
         * 有重复,默认的hashCode(哈希值返回每个对对象的地址值)比较结果不同, 被认为是不同对象,所以添加成功
         * 
         * 
         * 总结:
         * 对于自定义类型使用HashSet必须正确重写hashCode和equals方法
         */
        
        System.out.println("--------使用方法-------");
        new HashSetTest().method1();
    

    
    public void method1()
        //创建set对象
        Set<Integer> s1 = new HashSet<>();
        
        //添加元素
        s1.add(11);
        s1.add(12);
        s1.add(11);
        s1.add(14);
        
        System.out.println(s1);//[11, 12, 14]  基本引用类型自动去重
    

测试结果

Student [name=xiaoming, age=21]
Student [name=xiaojun, age=20]
--------使用方法-------
[11, 12, 14]

 

2,TreeSet集合

public class Teacher
    String name;
    int age;

    public Teacher2(String name, int age) 
        super();
        this.name = name;
        this.age = age;
    

    @Override
    public String toString() 
        return "Teacher [name=" + name + ", age=" + age + "]";
        

 

 

/*
 * 它实现了SortedSet这个接口,所以它有序
 * 排序必定要实现comparable接口,目的是保持元素有序
 * 可以保持集合有序状态,默认按自然顺序递增排序,也可以按照指定的比较器递增排序
 * 
 * 用没有参数的构造函数意味着以对象的comparaTo方法进行排序
 * 
 * 不需要覆写hashCode和equals的原因:
 *         TreeSet是红黑树结构,其主要使用的是在插入的时候根据你提供的比较规则插入, 二叉树
 */
public class TreeSetTest 
    public static void main(String[] args) 
        TreeSet<Teacher> t = new TreeSet<>();
        
        Teacher t1 = new Teacher("Jack", 43);
        Teacher t2 = new Teacher("Mary", 39);
        Teacher t3 = new Teacher("Jack", 43);
        Teacher t4 = new Teacher("John", 23);
        Teacher t5 = new Teacher("Cal", 23);
        Teacher t6 = new Teacher("Lory", 99);
        
        t.add(t1);
        t.add(t2);
        t.add(t3);
        t.add(t4);
        t.add(t5);
        t.add(t6);
        t.add(t6);
        
        /*
         * 直接进行输出报错:
         *         Teacher cannot be cast to java.lang.Comparable
         * 
         * 原因:
         *         用TreeSet存储对象时必须实现Comparable接口,它是一个有序的列表
         * 
         * 疑问:
         *         为何它不用重写hashCode和equals方法????
         */
        for (Teacher teacher : t) 
            System.out.println(teacher);
        
        
        
        //建立一个自己的nameComparactor
        class nameCompare implements Comparator<Teacher>

            @Override
            public int compare(Teacher g0, Teacher g1) 
                // TODO Auto-generated method stub
                return g0.name.compareTo(g1.name);
            
        

 

三,Map基本使用

//注意事项:使用自定义对象作为key时也要重写hashCode和equals方法

public class MapTest 
    
    public static void main(String[] args) 
        new MapTest().test1();
    
    
    void test1()
        //创建map对象
        Map<String , String> m1 = new HashMap<>();
        
        //添加元素  映射功能 键如果不存在返回null 如果存在则返回该值进行了修改
        m1.put("006", "yuan");
        m1.put("002", "dai");
        m1.put("005", null);
        m1.put("0019", "YY");
        m1.put("001", "jj");
        System.out.println(m1.put("004", "jack"));
        System.out.println(m1.put("001", "maryan"));
        
//        Map.Entry<String, String> ey = (Entry<String, String>) m1.entrySet();
        Set<Map.Entry<String, String>> entry1 = m1.entrySet();
        //用Map.Entry<>遍历map的键,值
        for(Map.Entry<String, String> entry: m1.entrySet())
            String k = entry.getKey();
            String v = entry.getValue();
        
        
        //获取key生成的集合
        Set<String> s1 = m1.keySet();
        System.out.println(s1);
        
        //获取value生成的集合
        Collection<String>  c1 = m1.values();
//        List<String> l1 = (List<String>) m1.values();//查看源码可知:不能强制转换为list,它不为list 没有索引
        System.out.println(c1);
//        System.out.println(l1);
        
        //生成新的集合,TreeMap
        Map<String, String> m2 = new TreeMap<>();
        m2.putAll(m1);
        System.out.println(m1);// 有序字典
        System.out.println(m2);//无序字典
    

 

以上是关于Java容器的主要内容,如果未能解决你的问题,请参考以下文章

Java并发工具类Java并发容器

java容器学习

Docker 容器 如何用java读取宿主机里的文件?

java容器中toArray的用法

Java学习笔记—多线程(同步容器和并发容器)

Java并发机制--同步容器与并发容器