Java库中的常用集合(Collection/List/Set/Map)
2016-11-13 20:25
746 查看
一、Collection<E> 接口
1.1、常用方法
/* *增删操作 */ boolean add(E e) boolean remove(Object o) /* *集合操作 */ //对于Set接口就是求并集,对于List接口就是将两列表连接起来 boolean addAll(Collection<? extends E> c) //对于Set接口就是求差集 boolean removeAll(Collection<?> c) //对于Set接口就是求交集 boolean retainAll(Collection<?> c) /* *查找某一个或几个元素在集合中是否存在 */ boolean contains(Object o) boolean containsAll(Collection<?> c)
以上方法都会涉及集合元素的比较,这些比较都是通过调用显式参数的equals()方法来完成的,所以需要重写equals()方法。
以上方法的隐式参数和显式参数都只要求实现了Collection接口即可,所以可以出现隐式参数和显式参数一者为Set,一者为List的情况(但这种情况,在实现正确的equals()方法的约束下,永远返回false)。
equals()方法重写示例:
/* *情形一:如果子类能够拥有自己的相等概念,则对称性需求将强制采用getClass进行检测 */ class Employee{ public String name; public int age; public double[] bwh; //... @Override public boolean equals(Object obj){ //equals()方法的入参必须为Object类型 if(this == obj) return true; if(obj == null) return false; if(getClass() != obj.getClass()) return false; Employee other = (Employee)obj; return Objects.equals(name,other.name) //引用类型比较 && age == other.age //基本类型比较 && Arrays.equals(bwh,other.bwh); //数组比较 } } /* *情形二:如果由超类决定相等的概念,那么就可以使用instanceof进行检测,这样可以在不同子类的对象之间进行相等的比较 */ class Employee extends SuperClassName{ public String name; public int age; public double[] bwh; //... @Override public boolean equals(Object obj){ if(this == obj) return true; if(obj == null) return false; if(!(obj instanceof SuperClassName)) return false; SuperClassName other = (SuperClassName)obj; //superName、superAge等是父类的属性 return Objects.equals(superName,other.superName) && superAge == other.superAge && Arrays.equals(superbwh,other.superbwh); } }
重写equals()方法的同时,也必须重写hashCode()方法:
class Employee{ public String name; public int age; public double height; public double[] bwh; //... @Override public int hashCode(){ int c = 7; //最好为质数。防止键的集聚 return c * Objects.hashCode(name) //引用类型的哈希值 + c * age //int型的哈希值 + c * new Double(height).hashCode() //double型的哈希值 + c * Arrays.hashCode(bwh); //数组的哈希值 } }
当equals()方法返回true时,两个对象的hashcode也必须相同;当equals()方法返回false时,两个对象的hashcode在大多数情况是不同的,在少数情况下相同。
集合类判断两个对象是否相等,是先判断hashcode是否相等,再判断equals()返回值是否为ture,只有两者都相等时,才认为该两个对象是相等的。所以若两个相同的对象有不同的hashcode,就会将两个相同的对象插入到Set或Map中。
所谓散列冲突,是指集合类在判断两个对象是不同的之后,将两者的hashcode经过运算,发现两者在桶(bucket)中的位置是相同的。两者的hashcode不相同时有可能出现散列冲突,两者的hashcode相同时一定会出现散列冲突。所以就算不同的对象有相同的hashcode,也不会影响集合类的正常运行。
1.2、迭代器方法 Iterator<E> iterator()
迭代器使用示例:Collection<String> c = new ArrayList<String>(); Iterator<String> iter = c.iterator(); while(iter.hasNext()){ String element = iter.next(); if(...){ iter.remove(); } }
只有对自然有序的集合使用迭代器添加元素才有实际意义。
——摘自《Core Java》
所以Collection接口的迭代器没有add()方法,而List接口的迭代器才有add()方法。
在执行 Iterator iter = c.iterator() 时,相当于生成了该集合的一个迭代器实例,若使用该迭代器实例以外的方法修改集合(包括集合自身的方法和其它迭代器实例的方法),就会抛出Concurrent ModificationException异常。
迭代器在add或remove时,会额外改变自己独有的游标,所以在遍历集合时进行增删操作不会出现误操作。
迭代器每次执行next()方法时,都会重新复制当前集合,所以迭代器可以实时反应集合的变化。
二、List<E> 接口
2.1、常用方法
//增 boolean add(E e) void add(int index, E e) //删 boolean remove(Object o) E remove(int index) //改 E set(int index, E element) //查 E get(int index) int indexOf(Object o) //获取子集合 List<E> subList(int fromIndex, int toIndex) //获取迭代器 ListIterator<E> listIterator() ListIterator<E> listIterator(int index)
2.2、迭代器方法 ListIterator<E> listIterator()
比Iterator多出来的方法://Iterator只有删和查的操作,ListIterator还增加了增和改的操作 void add(E e) void set(E e)
三、Set<E> 接口
3.1、常用方法
//增 boolean add(E e) //删 boolean remove(Object o)
四、Map<K,V> 接口
List接口、Set接口是继承自Collection接口的,而Map接口与Collection接口是平行的关系。4.1、常用方法
//增、改 V put(K key, V value) void putAll(Map<? extends K,? extends V> m) //查 V get(Object key) boolean containsKey(Object key) boolean containsValue(Object value) //删 V remove(Object key)
4.2、Map的视图
三种视图://键值对集 Set<Map.Entry<K,V>> entrySet() //键集 Set<K> keySet() //值集(不是集) Collection<V> values()
视图使用示例:
Map<String,Employee> staff = new HashMap<String,Employee>(); for(Map.Entry<String,Employee> entry : staff.entrySet()){ String key = entry.getKey(); //取键 Employee value = entry.getValue(); //取值 //... entry.setValue(e); //重新设值 }
注意点:
entrySet()和keySet()返回的Set,既不是HashSet也不是TreeSet,而是实现了Set接口的某个其它类的对象。同时Set接口扩展了Collection接口,因此可以与使用任何集合一样使用entrySet()和keySet()返回的Set。
——摘自《Core Java》
values()的返回类型是Collection而不是Set,是因为所谓“值集”并不是集,因为有可能重复。
五、类型转换
5.1 不同集合类之间的转换
//通过各自的构造函数 ArrayList(Collection<? extends E> c) LinkedList(Collection<? extends E> c) HashSet(Collection<? extends E> c)
关键点在于这些构造函数的入参都仅仅要求是Collection,So elegant!
5.2 集合类与数组之间的转换
/* *数组转换为集合类 */ String[] arr ={"a","b","c"}; List<String> list = Arrays.asList(arr); //此处list不可修改 //或直接 List<String> list = Arrays.asList("a","b","c"); List<String> arrList = new ArrayList<String>(list);//此处arrList可修改 /* *集合类转换为数组 */ List<String> arrList = new ArrayList<String>(); String[] arr = new String[arrList.size()]; arrList.toArray(arr);
六、Java库中的具体集合
——摘自《Core Java》
参考连接:
正确重写hashCode的办法
ArrayList源代码分析
Iterator的remove()和Collection的remove()
Arrays.asList()注意
相关文章推荐
- JAVA常用集合List、Set、Map区别及适用场景总结
- java 常用集合list与Set、Map区别及适用场景总结
- java 常用集合list与Set、Map区别及适用场景总结
- Java集合Collection、List、Set、Map使用详解
- java 常用集合list与Set、Map区别及适用场景总结
- Java基本概念:集合类(Collection)List/Set/Map的区别和联系
- java 常用集合list与Set、Map区别及适用场景总结
- 黑马程序员_java_集合框架_Collection_List_Set_Map_泛型
- java集合之Collection---set/map/list
- javascript面向对象实现java常用的1StringBuffer,Map,Collection,List,Set
- 【java读书笔记】——Collection集合之六大接口(Collection、Set、List、Map、Iterator和Comparable)
- java 集合 list map set collection
- 【java随记】——Collection集合之六大接口(Collection、Set、List、Map、Iterator和Comparable)
- java 常用集合list与Set、Map区别及适用场景总结
- java 集合架构--[Collection] [List] [Set] [Map] [集合工具类]
- java 常用集合list与Set、Map区别及适用场景总结
- 【java读书笔记】——Collection集合之六大接口(Collection、Set、List、Map、Iterator和Comparable)
- java 常用集合list与Set、Map区别及适用场景总结
- Java基本概念:集合类(Collection)List/Set/Map... 的区别和联系
- Java:常用集合类(List、Map、Set、Queue、Stack)