0007_Collection、Map集合类
2016-01-09 04:57
417 查看
java.util.Collection 是一个集合接口(集合类的一个顶级接口)。Collections 是一个包装类(工具类/帮助类)。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,用于对集合中元素进行排序、搜索以及线程安全等各种操作,服务于Java的Collection框架。
其直接继承的接口有List和Set。
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
打印出的结果为:
[align=left][10, 25, 2][/align]
[align=left][2, 10, 25]
[/align]
[align=left]打印出的值为:[/align]
[align=left]true[/align]
[align=left]true[/align]
[align=left]false[/align]
[align=left][People = [name=张三,age=30]][/align]
[align=left]此方法中添加了三个元素,使用remove方法时,remove字符串和Integer类型的值返回为true,remove实体类型的值却返回false。[/align]
[align=left]这是因为从集合中remove对象,集合类判断的是对象的equals,如果两个对象equals,则remove掉。String类型和Integer类型都重写了equals方法和hashcode方法。[/align]
[align=left]
[/align]
[align=left]容器类的对象在调用remove(),contains()等方法时需要比较对象是否相等,这会涉及到对象类型的equals方法和hashcode方法。一般来说使用equals进行比较(当对象用在Map接口作为键key时,会使用hashcode方法做比较。因为hashcode相当于字典里的索引,效率比较高),对于自定义的类型,需要重写equals和hashcode方法以实现对象相等的规则。[/align]
[align=left]
[/align]
[align=left]两个对象equals,则两个对象的hashcode一定相等。[/align]
[align=left]两个对象hashcode相等,两个对象不一定equals。[/align]
[align=left]两个对象如果要equals,则两个对象的hashcode一定equals,所以重写equals就必须重写hashcode方法。[/align]
重写People的equals方法(不重写hashcode方法):
[align=left]此时打印的结果为:[/align]
[align=left]true[/align]
[align=left]true[/align]
[align=left]true[/align]
[align=left][][/align]
[align=left]此时没有重写hashcode方法,也remove掉了。[/align]
[align=left]测试Map:[/align]
[align=left]此时打印出来的结果为:[/align]
[align=left]{People = [name=张三,age=30]=aaa}[/align]
[align=left]结果并没有remove掉。[/align]
[align=left]重写People的hashcode方法:[/align]
[align=left]在此调用main方法,此时打印结果为空。可见移除掉了。[/align]
[align=left]对于重写equals和hashcode方法后,使用remove()或者contains()方法在各类集合中体现如下:[/align]
[align=left]List的实现类(ArrayList,LinkedList,Vector)都实现了Iterator接口。所以可以使用Iterator遍历。[/align]
[align=left]Map的遍历:[/align]
[align=left]HashMap没有iterator()方法,但它有一个values()方法,调用此方法后返回的是Collection对象,通过返回的对象可调用iterator()方法,从而实现取数据。[/align]
[align=left]Map特点:元素按键值对存储,无放入顺序 [/align]
[align=left]Set特点:元素无放入顺序,元素不可重复[/align]
[align=left]LinkedList:链式存储结构,查找慢而操作快。[/align]
Vector:线程安全,速度慢。
HashSet和TreeSet的区别:
HashSet是通过HashMap实现的,TreeSet是通过TreeMap实现的,只不过Set用的只是Map的key。
TreeSet类不仅实现了Set接口,还实现了java.util.SortedSet接口,从而保证在遍历集合时按照递增的顺序获得对象。遍历对象时可能是按照自然顺序递增排列,所以存入用TreeSet类实现的Set集合的对象必须实现Comparable接口;也可能是按照指定比较器递增排列,即可以通过比较器对用TreeSet类实现的Set集合中的对象进行排序。
HashSet类按照哈希算法来存取对象,当向集合中加入一个新对象时,会调用对象的HashCode()方法得到对象的哈希码,然后根据这个码计算出对象在集合中存储的位置。
[align=left]程序运行会报错:[/align]
Exception in thread "main"java.lang.ClassCastException:
com.xy.domain.People cannot be cast to java.lang.Comparable
TreeSet和TreeMap在使用remove()方法时,不但要重写equals和hashcode方法,还要继承
[align=left]Comparable接口,重写Comparable方法。[/align]
其直接继承的接口有List和Set。
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
public static void main(String[] args) { List<Integer> list = new ArrayList<Integer>(); list.add( new Integer(10)); list.add( new Integer(25)); list.add( new Integer(2)); System. out.println(list); Collections. sort(list); System. out.println(list); }
打印出的结果为:
[align=left][10, 25, 2][/align]
[align=left][2, 10, 25]
[/align]
1.测试remove()方法.(equals和hashcode)
public static void main(String[] args) { Collection c = new ArrayList<Object>(); c.add("test"); c.add(new Integer(100)); c.add(new People("张三",30)); System.out.println(c.remove( "test")); System. out.println(c.remove(new Integer(100))); System. out.println(c.remove(new People("张三",30))); System. out.println(c); }
[align=left]打印出的值为:[/align]
[align=left]true[/align]
[align=left]true[/align]
[align=left]false[/align]
[align=left][People = [name=张三,age=30]][/align]
[align=left]此方法中添加了三个元素,使用remove方法时,remove字符串和Integer类型的值返回为true,remove实体类型的值却返回false。[/align]
[align=left]这是因为从集合中remove对象,集合类判断的是对象的equals,如果两个对象equals,则remove掉。String类型和Integer类型都重写了equals方法和hashcode方法。[/align]
[align=left]
[/align]
[align=left]容器类的对象在调用remove(),contains()等方法时需要比较对象是否相等,这会涉及到对象类型的equals方法和hashcode方法。一般来说使用equals进行比较(当对象用在Map接口作为键key时,会使用hashcode方法做比较。因为hashcode相当于字典里的索引,效率比较高),对于自定义的类型,需要重写equals和hashcode方法以实现对象相等的规则。[/align]
[align=left]
[/align]
[align=left]两个对象equals,则两个对象的hashcode一定相等。[/align]
[align=left]两个对象hashcode相等,两个对象不一定equals。[/align]
[align=left]两个对象如果要equals,则两个对象的hashcode一定equals,所以重写equals就必须重写hashcode方法。[/align]
重写People的equals方法(不重写hashcode方法):
@Override public boolean equals(Object obj) { if(obj instanceof People){ People people = (People) obj; return (name.equals(people.name )&&age.equals(people. age)); } return super .equals(obj); }测试:
public static void main(String[] args) { List<Object> c = new ArrayList<Object>(); c.add( "test"); c.add( new Integer(100)); c.add( new People("张三" ,30)); System .out .println(c.remove("test")); System .out .println(c.remove(new Integer(100))); System .out .println(c.remove(new People( "张三",30))); System .out .println(c); }
[align=left]此时打印的结果为:[/align]
[align=left]true[/align]
[align=left]true[/align]
[align=left]true[/align]
[align=left][][/align]
[align=left]此时没有重写hashcode方法,也remove掉了。[/align]
[align=left]测试Map:[/align]
public static void main(String[] args) { Map<Object,String> map = new HashMap<Object, String>(); map.put( new People("张三" ,30), "aaa"); map.remove( new People("张三" ,30)); System. out.println(map); }
[align=left]此时打印出来的结果为:[/align]
[align=left]{People = [name=张三,age=30]=aaa}[/align]
[align=left]结果并没有remove掉。[/align]
[align=left]重写People的hashcode方法:[/align]
@Override public int hashCode() { return name .hashCode (); }
[align=left]在此调用main方法,此时打印结果为空。可见移除掉了。[/align]
[align=left]对于重写equals和hashcode方法后,使用remove()或者contains()方法在各类集合中体现如下:[/align]
不重写 | 重写equals | 重写hashcode | 同时重写 | |
List集合(ArrayList,LinkedList,Vector) | false | true | false | true |
Set(HashSet) | false | false | false | true |
Map (HashMap,HashTable) | false | false | false | true |
2.遍历集合
[align=left]List的遍历:[/align][align=left]List的实现类(ArrayList,LinkedList,Vector)都实现了Iterator接口。所以可以使用Iterator遍历。[/align]
public static void IteratorList(List list){ //1.基本遍历 for(int i=0;i<list.size();i++){ System. out.print(list.get(i).toString()); } //2.foreach 遍历 for (Object object : list) { System. out.print(object.toString()); } //3.iterator遍历 for(Iterator<String> it=list.iterator();it.hasNext();){ System. out.print((String)it.next()); } }
[align=left]Map的遍历:[/align]
[align=left]HashMap没有iterator()方法,但它有一个values()方法,调用此方法后返回的是Collection对象,通过返回的对象可调用iterator()方法,从而实现取数据。[/align]
public static void IteratorMap(Map<String,String> map){ //1.keySet for(String key : map.keySet()){ System. out.println("key=" +key+",value="+map.get(key)); } //2.entrySet Set<Map.Entry<String, String>> ms = map.entrySet(); Iterator it = ms.iterator(); while(it.hasNext()){ Map.Entry<String, String> entry = (Entry<String, String>) it.next(); System. out.println("key=" +entry.getKey()+",value="+entry.getValue()); } //遍历entrySet for(Map.Entry<String, String> entry:map.entrySet()){ System. out.println("key=" +entry.getKey()+",value="+entry.getValue()); } //4.map.values for(String s:map.values()){ System. out.println("value=" +s); } }
3.各类集合区别
List和Set和Map的区别:
[align=left]List特点:元素有放入顺序,元素可重复 [/align][align=left]Map特点:元素按键值对存储,无放入顺序 [/align]
[align=left]Set特点:元素无放入顺序,元素不可重复[/align]
ArrayList,LinkedList, Vector的区别:
[align=left]ArrayList:顺序存储结构,查找快而操作慢(移动数组)。非线程安全,速度快。[/align][align=left]LinkedList:链式存储结构,查找慢而操作快。[/align]
Vector:线程安全,速度慢。
HashMap,HashTable的区别:
HashMap非线程安全,高效,支持null;HashTable线程安全,低效,不支持null。HashSet和TreeSet的区别:
HashSet是通过HashMap实现的,TreeSet是通过TreeMap实现的,只不过Set用的只是Map的key。TreeSet类不仅实现了Set接口,还实现了java.util.SortedSet接口,从而保证在遍历集合时按照递增的顺序获得对象。遍历对象时可能是按照自然顺序递增排列,所以存入用TreeSet类实现的Set集合的对象必须实现Comparable接口;也可能是按照指定比较器递增排列,即可以通过比较器对用TreeSet类实现的Set集合中的对象进行排序。
HashSet类按照哈希算法来存取对象,当向集合中加入一个新对象时,会调用对象的HashCode()方法得到对象的哈希码,然后根据这个码计算出对象在集合中存储的位置。
4.TreeSet和TreeMap
public static void testTreeSet(){ Map mt = new TreeMap<People, String>(); Set t = new TreeSet<People>(); mt.put(new People("aa",23), "a"); t.add(new People("a",2)) ; mt.remove( new People("aa" ,23)); t.remove( new People("a" ,2)); }
[align=left]程序运行会报错:[/align]
Exception in thread "main"java.lang.ClassCastException:
com.xy.domain.People cannot be cast to java.lang.Comparable
TreeSet和TreeMap在使用remove()方法时,不但要重写equals和hashcode方法,还要继承
[align=left]Comparable接口,重写Comparable方法。[/align]
@Override public int compareTo(Object o) { People p = (People)o; return this .age -p.age; }此时运行程序就不会报错了。
相关文章推荐
- android Google Map获取地理位置信息的方法
- Spark RDD API详解(一) Map和Reduce
- Python中map()函数浅析
- Android使用Google Map浅谈
- Erlang中的映射组Map详细介绍
- Rails Routes中new、collection、member的区别浅析
- c++中map的基本用法和嵌套用法实例分析
- JavaScript中实现Map的示例代码
- jquery中map函数与each函数的区别实例介绍
- jquery中map函数遍历数组用法实例
- jquery与google map api结合使用 控件,监听器
- 解决 The Controls collection cannot be modified because the control contains code blocks
- jquery遍历数组与筛选数组的方法
- JavaScript中实现map功能代码分享
- 用json方式实现在 js 中建立一个map
- Android Map新用法:MapFragment应用介绍
- java集合框架的体系结构详细说明
- js Map List 遍历使用示例
- java实现遍历Map的方法
- velocity显示List与Map的方法详细解析