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)是求并集

接下篇。。。休息一下下啦。。。

posted @ 2013-09-09 15:58  董文博  阅读(176)  评论(0编辑  收藏  举报