java学习笔记之容器(一)
Collection的两个子接口
Set :没有顺序,不可重复
List:有顺序,可重复
这里重复的标准是互相equals();
Map接口
Key---Value
1 package com.zhuoyue.rq; 2 3 import java.util.ArrayList; 4 import java.util.Collection; 5 6 public class Test { 7 public static void main(String[] args) { 8 Collection c = new ArrayList(); 9 c.add("hello"); 10 c.add(100);//这里有自动打包,关于int型的100 11 System.out.println(c.size()); 12 System.out.println(c);//这里会自动解包 13 } 14 }
1 package com.zhuoyue.rq; 2 3 import java.util.Collection; 4 import java.util.HashSet; 5 6 public class Test { 7 public static void main(String[] args) { 8 Collection c = new HashSet(); 9 c.add("hello"); 10 c.add(100); 11 c.add(100);//由于set中不能有重复元素,这里编译时没有错误,运行时忽略这句,不起作用 12 c.add(200); 13 System.out.println(c.size()); 14 System.out.println(c); 15 } 16 }
这里我们穿插一下equals和hashcode这两个方法
当我们在set容器中添加对象的时候,编译器会检查两个对象是否相同(equals),如果相同,不添加,不同的话,添加
一些常用类如String,Integer均重写了equals和hashcode这两个方法
我们再想,假如容器中有1000个元素,这时需要再添加1个元素,那是不是要调用1000次equals和每个元素进行比较呢?
我们来看hashcode的作用,很据内存地址来算这个对象应该存放在set容器的哪个地方,相同的内存地址一定会有相同的位置(相同的位置也可能会对应不同的内存地址),所以,不同的对象地址可能会算出相同的位置,这时调用equals来看,这两个对象的内容是否相同,如果相同,不存,反之,继续调用hashcode找到位置存进去。
但是这里有一个疑问,字符串内容相同的两个不同字符串对象的hashcode是相同的,这是一定的,hashcode不是很据内存地址决定的吗?两个内存地址怎么会相同呢?
这里,我好像进入了一个误区,以上思路先放一放,看下面正确的几点吧
两个对象互相equals,那么他们的hashcode一定相同
两个对象hashcode不同,那么他们一定不equals
这是两个重写的原则
1 package com.zhuoyue.rq; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 public class HashEqualsTest { 7 public static void main(String[] args) { 8 Set hs = new HashSet(); 9 hs.add(new Student(1, "zhangsan")); 10 hs.add(new Student(2, "lisi")); 11 hs.add(new Student(3, "wangwu")); 12 hs.add(new Student(1, "zhangsan")); 13 System.out.println(hs); 14 } 15 } 16 17 class Student { 18 int num; 19 String name; 20 21 Student(int num, String name) { 22 this.num = num; 23 this.name = name; 24 } 25 26 public int hashCode() { 27 return num * name.hashCode();//假如name和num相同(equals),hashcode一定相同;hashcode不同,一定不equals 28 } 29 30 public boolean equals(Object o) { 31 Student s = (Student) o; 32 return num == s.num && name.equals(s.name); 33 } 34 35 public String toString() { 36 return num + ":" + name; 37 } 38 39 }
执行结果:
分析:我们看到相同的元素已经加不进去了,而且还看到,hashcode的重写是先看内容的,不是内存地址转化的hashcode(彻底蒙圈啦)
和前面教的理论完全不一致啊
见文:http://blog.csdn.net/winer2008/article/details/4059789
hashcode和equals的内容就说到这里,接着学习容器啊
remove的时候也会调用equals方法,相同的时候才会被remove
Map键也会调用equals和hashcode方法
Iterator接口
举个栗子:
1 package com.zhuoyue.rq; 2 3 import java.util.HashSet; 4 import java.util.Iterator; 5 import java.util.Set; 6 7 public class IteratorTest { 8 9 public static void main(String[] args) { 10 Set s = new HashSet(); 11 s.add("Michael"); 12 s.add("Jackson"); 13 s.add("Phillip Phillips"); 14 System.out.println(s); 15 Iterator i = s.iterator(); 16 while(i.hasNext()){ 17 //i.remove();一开始游标左边没有元素,所以不能remove 18 String s1 = i.next().toString(); 19 System.out.println(s1); 20 } 21 } 22 23 }
再举个例子:
1 package com.zhuoyue.rq; 2 3 import java.util.HashSet; 4 import java.util.Iterator; 5 import java.util.Set; 6 7 public class IteratorTest2 { 8 9 public static void main(String[] args) { 10 Set s = new HashSet(); 11 s.add("Phillip Phillips"); 12 s.add("Michael"); 13 s.add("Jackson"); 14 for(Iterator i = s.iterator();i.hasNext();){ 15 if(i.next().toString().length()>7){ 16 i.remove(); 17 } 18 } 19 System.out.println(s); 20 } 21 22 }
补充知识:增强for
举个栗子:
1 package com.zhuoyue.rq; 2 3 import java.util.ArrayList; 4 import java.util.Collection; 5 6 public class EnhancedFor { 7 8 public static void main(String[] args) { 9 int[] arr = {1,2,3,4,5,6}; 10 for(int i:arr){//把arr中的每个元素放入i中,然后输出 11 System.out.println(i); 12 } 13 14 Collection c = new ArrayList(); 15 c.add("1"); 16 c.add("2"); 17 c.add("3"); 18 for(Object o:c){//把c中的每个元素放入o中,然后输出 19 System.out.println(o); 20 } 21 } 22 23 }
Set方法举例:
分析:sn.retainAll(s2)是求两个集合的交集,su.addAll(s2)是求并集
接下篇。。。休息一下下啦。。。