史上最全讲解:java中的List,Set,Map
文章目录
java中的List,Set,Map,Properties
容器之间的关系
容量可以随时扩充的容器来装载我们的对象。这就是我们今天要学习的容器类,或者叫集合框架。集合框架的简单的体系结构如下:
容器之间的体系结构十分复杂
List类
List接口特点:
- 有序,可以重复
- 遍历方法:普通for循环,增强for循环,Iterator迭代器,ListIterator迭代器
ArrayList:
- 数据结构:根据可变数组实现的
- 特点:有索引,查询效率高,增删效率低
- 扩容机制:使用copyOf进行动态扩容,每次扩若为原容量的1.5倍
Vector:
与ArrayList很像,区别如下:
- 线程安全
- 每次扩容为原容量的2倍
LinkedList:
- 数据结构:双向链表实现
- 特点:查询效率低,增删效率高
Set类
Set类的特点
- 无序不可重复
- 遍历:增强for和Iterator迭代器
HashSet
- 底层结构:哈希表实现的(数组+链表+红黑树)
每个链表上的数据大于8 的时候会变成红黑树排序,数据过多时会自动平衡二叉树.此时在该特定链表上的数据是有序的(默认升序排序) - 特点:查询效率高,增删效率高,但是无序
- hashset就是hashmap中的key,hashset底层就是hashmap
- hashSet()默认是16大小,加载因子0.75(可以修改,数据大于16*0.75=12以后就自动扩容)
- 内容相同hashcode一定相同,hashcode相同,内容不一定相同,到底是不是相同需要调用equals方法
- hashcode不同内容一定不同 不需要调用equals方法 提高效率
- hashset无序的,不可重复,对于java提供的数据类型,java自身会自动提供去重方法,对于自定义的数据类型,需要自己重写hashcode和equals方法,
- Object里的equals比较的是对象的地址,hashcode也是根据地址计算的。重写之后hashcode比较的是属性,equals比较的也是属性。避免出现重码不同属性,必须用equals比较一下。也就是说hashcode方法是自动调用的,必须重写。equals也是。
- 当只重写equals不重写hashcode的时候,那么,对象在调用hashcode的时候会调用自身的hashcode方法来对对象的地址就行比较,由于每次new对象系统都会分配新的存储空间,当存入相同的对象是,在hashcode这一步得到的hashcode值不相同那么便不会去进行重写的equals比较,所以达不到去重的效果.
HashTable
与HashSet很像,但是线程安全效率低
TreeSet
- 无序不可重复(这里的重复: TreeSet有序 这里的有序指的是放入的元素(java自己的数据结构)会自动升序,自定义数据类型要自己给定排序规则,)
- 底层结构:红黑树进行存储(默认升序)
- 升序排序
- 自定义的数据类型需要自己给定排序规则,比如PerSon类中根据身高进行排序,需要使用到内部比较器(在Person类中实现Comporable)或者外部比较器(使用一个类实现Comporator接口,匿名内部类或者是lambda表达式,在new TreeSet()的时候作为带参构造器的参数传入)
- 内部比较器:在定义的类中实现Comporable接口,重学compareTo方法,在方法中定义比较规则
- 外部比较器:实现Comporator接口,重写compare()方法,方法的额内部定义比较规则
- 所有的类不写hashcode,toString,equals,那么则默认继承Object类的这些方法
Map类
Map类的特点
- key值的集合就是Set,所以key值具有Set的相关性质
- 键值对类型,键key值不可重复,唯一
- 若有相同的key-value,则默认后面的value会覆盖前面的value
HashMap
- HashMap的键key是hashSet,所以hashMap去重问题和hashset一样,如果是java定义的数据类型那么会自动去重,之所以自动去重是因为java定义的数据类型重写了hashcode和equals方法,如果是自己定义的数据类型则需要自己重写hashcode和equals方法.比如自定义Person类是Map中的key值,那么需要对Person进行重写hashCode和equas方法
TreeMap
- TreeMap的去重+排序,根据Map的key进行计算
- java定义的数据类型自动回复去重和排序(一般只有tree才会排序).自定义数据类型需要实现比较器
- Hash(HashSet/HashMap)与Tree(TreeSet/TreeMap)比较:
1.都是不可重复的,无序的,在去重的时候自定义数据类型都需要重写hashcode和equals方法
2.Tree在排序的时候,自定义类型需要实现Compatator接口(compare方法外部比较器)或者继承Comporatable(compareTo)内部比较器
Properties
- 特殊的Map,键和值都是String