集合与数组

01集合:

集合框架图
单列集合
List:有索引,有顺序,能重复的
Set:无索引,无数序,不能重复的
Hashset:
查看源码,发现Hashset底层是个Hashmap,只不过value都是空的object
Map是不允许key相同的,所以Hashset中的值是唯一的
TreeSet:
底层也是Map,value也是空的object,同样能保证值的唯一性

问题1:怎样保证HashSet中存储的自定义对象的唯一性
注:如果对象的属性都相同,则这里看成是同一个对象
HashSet实际上是HashMap的key,保证唯一就是要让jvm将属性相同的对象当作同一个key
那么jvm是怎么确定同一个key的呢?
查看源码,HashMap的put方法中用到了对象的hash值,和对象的equals方法
可以理解成如果对象的hash值不同,就不能存在Map中,而每一个对象的hash值肯定是不一样的(hash值是通过对象的地址值根据一种算法算出来的),
所以肯定是可以存的,显然这里不能用Object类中原始的获得hash值的方法
所以要重写hash方法和equals方法,保证对象如果属性是一致的,则hash值一样,这样在Map.put的时候调用自身的hash方法和equals方法,如果属性一致的话就当作 
同一个对象,就不会存在Map的key中,这样保证元素的唯一性
重写hash方法和equals方法:可以使用快捷键

问题2:TreeSet是怎样自定义排序的
TreeSet底层使用了二叉树算法
两种方式如下:

 1 public class Stu implements Comparable<Stu>{//自定义对象的排序方法:第一种
 2     private String name;
 3     private int age;
 4     public Stu() {
 5         super();
 6     }
 7     public Stu(String name, int age) {
 8         super();
 9         this.name = name;
10         this.age = age;
11     }
12     public String getName() {
13         return name;
14     }
15     public void setName(String name) {
16         this.name = name;
17     }
18     public int getAge() {
19         return age;
20     }
21     public void setAge(int age) {
22         this.age = age;
23     }
24     //自定义类判断对象是否一样,为什么要重写h和e方法
25     @Override
26     public int hashCode() {
27         final int prime = 31;
28         int result = 1;
29         result = prime * result + age;
30         result = prime * result + ((name == null) ? 0 : name.hashCode());
31         return result;
32     }
33     @Override
34     public boolean equals(Object obj) {
35         if (this == obj)
36             return true;
37         if (obj == null)
38             return false;
39         if (getClass() != obj.getClass())
40             return false;
41         Stu other = (Stu) obj;
42         if (age != other.age)
43             return false;
44         if (name == null) {
45             if (other.name != null)
46                 return false;
47         } else if (!name.equals(other.name))
48             return false;
49         return true;
50     }
51     //按照年龄来排序
52     //这种方式一般不用,比较的时候直接在定义TreeSet的时候写比较器,这样不会对其它地方产生影响
53     @Override
54     public int compareTo(Stu o) {
55         return (this.age -o.age);
56     }
57 }
 1         TreeSet<Stu> ts = new TreeSet<>(//自定义对象的排序方法:第二种
 2             //比较器
 3             new Comparator<Stu>() {
 4                 @Override
 5                 public int compare(Stu o1, Stu o2) {
 6                     // TODO Auto-generated method stub
 7                     int num = o1.getAge()-o2.getAge();
 8                     return num == 0 ? 1 : num;
 9                 }
10             }    
11         );

问题3:TreeMap怎样实现自定义对象的key排序

看源码发现TreeMap的put方法里面定义了比较器

实现排序的方法如下:

        TreeMap<Student, String> tm = new TreeMap<>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                int num = s1.getName().compareTo(s2.getName());
                return num == 0 ? s1.getAge() - s2.getAge() : num;   
            }
        });
原文地址:https://www.cnblogs.com/jaro/p/9001961.html