集合根据存储方式的不同分为两大类:实现Collection接口类下的集合 和 实现Map接口类下的集合
Collection(由于继承了Interable接口,所以以下所有的都是可遍历的):
Collection接口下的所有的集合都是以单个元素进行存储的,下面有两个大的子类接口,分别是List接口和Set接口。(List接口和Set接口都继承了Collection接口,而Collection接口又继承了Interable接口)
List接口下的所有实现类的集合都是有序且可重复的,并且可以用下标来表示,分别有:
ArrayList:底层是使用的数组这种数据结构。
LinkedList:底层是使用的双向链表这种数据结构。
Vector:底层是使用的数组这种数据结构,和ArrayList不同的地方是,Vector是线程安全的,但是这同时也代表着效率较低,所以使用的不多。
Set接口下所有实现类的集合都是无序且不重复的,分别有:
HashSet:底层是使用的哈希表这种数据结构。
TreeSet:底层是使用的二叉树这种数据结构。但是由于实现了SortedSet接口(SortedSet接口继承了Set接口),里面存储的元素会自动按从小到大进行排序。在new TreeSet这个集合的时候,底层其实是new了一个TreeMap,然后将元素存到了TreeMap的key部分里面就等于存到了TreeSet里面。
Map:
Map接口下的所有集合都是以键值对(key和value)的方式来存储的。不可以用迭代器(Iterator())的方法来遍历,因为Map并没有继承Iterable接口。
HashMap:底层是使用的哈希表这种数据结构。如果将元素装入HashSet中,其实就是将元素装到了HashMap的key部分。(具体解释可以看源码)
HashTable:底层是使用的哈希表这种数据结构,但是由于是线程安全的,所以效率较低,使用的很少。
Properties:继承了HashTable,所以也是线程安全的,但是里面存元素的要求是,键值对中的key和value都必须是String类型的,不支持其他类型。
TreeMap:底层是使用的二叉树这种数据结构。如果将元素装入TreeSet中,其实就是将元素装到了TreeMap的Key部分中。并且和HashMap不同的是,装入TreeMap的键值对会根据key从大到小进行排序(因为key部分装的内容其实是TreeSet中的内容,而TreeSet会自动进行排序,并且TreeMap继承了SortedMap接口,SortedMap接口继承了Map接口)。
List中使用迭代器的遍历方式:
但是需要注意的是,在使用迭代器的时候,集合的结构是不允许发生变化的。
如果集合的结构发生变化,那么迭代器需要重新获取。
在删除的时候可以选择迭代器中的remove方法。迭代器中的remove方法删除的是当前迭代器所指向的元素。
(迭代器中一共有3个方法,hasNext(),next(),remove())
List中的contains()方法:
测试List中的contains方法,这个方法的底层调用了equals方法,由于这时候的User没有重写equals方法,没有重写equals方法的时候,默认继承的Object类中的equals方法,所以比较的是地址。所以在进行测试的时候,调用contains方法会显示这个List中没有我们要找的user对象。
而如果我们想要让contains方法比较的是内容而不是地址,那就需要重写User类的equals方法。
此时,调用contains方法的结果就是,显示List集合中有我们要找的User对象。
List中的remove()方法:
同样的,remove()方法底层也是调用了equals()方法。
重写equals方法前:
重写equals方法后:
List中特有的(Collection接口中没有的)方法:
void add(int index,Object element) :
collection中的add方法都是向末尾添加元素,而List中的add方法可以向选择好的下标位置插入元素,并且使每一个后面的元素依次后移一位。
Object get(int index)
Object remove(int index)
void set(int index,Object element):
将规定位置下标的元素设定成我们想要的。