Collection集合特点:每个元素可以存储一条信息,值。
Map集合特点:每个元素可以存储两条信息,键值对。
Collection的子接口有 List 和 Set
List
可以存储重复的元素 它的实现类有 ArrayList、Vector、LinkedList
区别:
ArrayList采用数组的结构存储元素,查询比较快,增删改较慢。线程不安全,效率高。
Vector采用数组的结构存储元素,查询比较快,增删改较慢。线程安全,效率低。
LinkedList采用链表结构存储元素,查询较慢,增删改较快。线程不安全,效率高。
遍历(以ArrayList为例):
List<String> a=new ArrayList();
a.add("aaa");
a.add("bbb");
a.add("ccc");
a.add("ddd");
a.add("aaa");
a.add("eee");
a.add("aaa");
a.add("fff");
①fori 根据下标
for (int i = 0; i < a.size(); i++) {
System.out.println(a.get(i));
}
②增强for
for(String s : a){
System.out.println(s);
}
③使用迭代器Iterator
Iterator it = a.iterator();
while(it.hasNext()){
String s = it.next();
System.out.println(s);
}
④forEach----λ(Lambda)表达式
a.forEach((s)->{
System.out.println(s);
});
Set
Set不能存储重复的元素
Set集合限制了add方法!!!
如果该元素存在,那么不插入,返回false。
作用:自动去重!!!
它的实现类有 HashSet、TreeSet、LinkedHashSet
HashSet
HashSet有以下特点
① 不能保证元素的排列顺序,顺序有可能发生变化
②不是同步的,线程不安全,效率高。
③集合元素可以是null,但只能放入一个null
当向HashSet结合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在HashSet中存储位置。
简单的说,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相 等
注意,如果要把一个对象放入HashSet中,重写该对象对应类的equals方法,也应该重写其hashCode()方法。其规则是如果两个对 象通过equals方法比较返回true时,其hashCode也应该相同。另外,对象中用作equals比较标准的属性,都应该用来计算 hashCode的值。
LinkedHashSet
LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起 来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。
LinkedHashSet在迭代访问Set中的全部元素时,性能比HashSet好,但是插入时性能稍微逊色于HashSet。
TreeSet类
TreeSet是SortedSet接口的唯一实现类,TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序 和定制排序,其中自然排序为默认的排序方式。向TreeSet中加入的应该是同一个类的对象。
TreeSet判断两个对象不相等的方式是两个对象通过equals方法返回false,或者通过CompareTo方法比较没有返回0。
遍历:因为没有下标所以Set集合只能用 增强for 、迭代器Iterator 和 forEach----λ(Lambda)表达式 来进行遍历。
HashSet的去重原理:
元素重复,需同时满足两个条件:
(1)两个元素的hashCode()相等;
(2)两个元素使用equals(..)比较,返回true。
String和八个包装类都重写了hashCode和equals方法。
普通类:需要我们自己重写hashCode和equals方法。
Map
每个元素由两部分构成,一部分叫键,一部分叫值。
键是唯一的,每个元素的键不能相同,而值是可以相同的。
Map的实现类:HashMap 、HashTable 、 TreeMap
HashMap:基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变。为了优化HashMap空间的使用,您可以调优初始容量和负载因子。
HashTable:实现一个哈希表,该哈希表将键映射到相应的值。任何非 null 对象都可以用作键或值,即不允许null键null值。
TreeMap:基于红黑树实现。TreeMap没有调优选项,因为该树总处于平衡状态。不允许null键,允许null值。
HashMap:适用于在Map中插入、删除和定位元素。
HashTable:单线程环境下,性能低,适用于完全的线程安全。
Treemap:适用于按自然顺序或自定义顺序遍历键(key)。
总结:
HashMap通常比TreeMap快一点(树和哈希表的数据结构使然),建议多使用HashMap,在需要排序的Map时候才用TreeMap,仅在你需要完全的线程安全的时候使用Hashtable。
遍历:
Map<Intager,String> map=new HashMap();
map.put(1001,"zhangsan");
map.put(1002,"lisi");
map.put(1003,"wangwu");
map.put(1004,"maliu");
map.put(1005,"lisi");
①获取所有元素的键,以set集合返回
Set<Integer> ks = map.keySet();
ks.forEach((k)->{
System.out.println(k);
});
②获取所有元素的值,以Collection集合返回
Collection<String> vs = map.values();
vs.forEach((v)->{
System.out.println(v);
});
③获取所有的键值对,以Set集合返回 每个键值对使用Map.Entry类型存储
Set<Map.Entry<Integer, String>> entries = map.entrySet();
for (Map.Entry<Integer, String> e: entries){
System.out.println(e.getKey()+" "+e.getValue());
}
④先找到所有元素的键,然后在根据键找值
Set<Integer> ks = map.keySet();
for (Integer k:ks){
String v = map.get(k);
System.out.println(k+" "+v);
}