集合在Java里面的作用非凡,我们常用的有Set,List和Map三种,我们先熟悉一下Set,特别是HashSet的使用
1.package collection.lession2;
2.1.import java.util.HashSet;
1.import java.util.Set;
1.1./**
1. *认识Set集合之HashSet。<br>
2. * Set用来保存不允许重复的数据。可以是任何对象类型。<br>
3. * JDK5以后,主类型可以通过autobox 放入Set里面。
4. *
7. */1.public class Lession2 {
2.1. public static void main(String[] args) {
2. // 普通测试1. testNormal();
2.1. // 测试HashSet的特殊性1. testForHashSet();
2. testForHashSet2();
3. }
4.1. /**
2. * 测试保存混合类型的数据.
3. */1. public static void testNormal() {
2. System.out.println("----- testNormal -----------");
3. // Set有多个实现,我们先看看最常用的HashSet1. Set set = new HashSet();
2. // 添加一个字符串1. set.add("字符串");
2. // 添加一个整数对象1. set.add(new Integer(1));
2. // 利用JDK5的特性,增加一个浮点数1. set.add(123.45);
2.1. // 我们看看集合里对象的数量1. System.out.println(set.size());
2.1. // 我们尝试增加一个重复的字符串1. set.add("字符串");
2.1. // 我们再次看看集合里对象的数量1. System.out.println(set.size());
2.1. // 我们来测试看看是否集合里包含了某个数据1. System.out.println(set.contains(123.45));
2.1. // 我们从里面把这个浮点数删除1. set.remove(123.45);
2.1. // 我们再次看看集合里对象的数量1. System.out.println(set.size());
2. }
3.1. /**
2. * 专门针对HashSet的测试。
3. */1. public static void testForHashSet() {
2. System.out.println("----- testForHashSet -----------");
3. HashSet<MyObject> set = new HashSet<MyObject>();
4.1. // 增加一个null对象1. set.add(null);
2. // 我们再次看看集合里对象的数量1. System.out.println(set.size());
2. // 再次增加一个null看看1. set.add(null);
2. // 我们再次看看集合里对象的数量1. System.out.println(set.size());
2.1. MyObject obj = new MyObject("java2000", 2);
2. set.add(obj);
3.1. obj = new MyObject("csdn", 10);
2. set.add(obj);
3.1. // 我们再次看看集合里对象的数量1. System.out.println(set.size());
2.1. // 判断是否包含某个对象1. System.out.println(set.contains(obj));
2.1. obj = new MyObject("java2000_net", 2);
2. set.add(obj);
3.1. // 我们再次看看集合里对象的数量1. System.out.println(set.size());
2.1. // 我们尝试把obj再次放入set看看1. // 并没有增加,因为是重复的1. set.add(obj);
2. System.out.println(set.size());
3.1. // 我们构造一个新的对象,内容和前面的相同1. obj = new MyObject("java2000_net", 2);
2. set.add(obj);
3. System.out.println(set.size());
4.1. // 我们修改一下obj里面的年龄,再看看1. obj.setAge(3);
2.1. // 我们再测试看看是否包含此对象。1. // 请注意,我们这个obj和前面的obj是同一个对象1. // 我们仅仅修改了一下我们的年龄1. System.out.println(set.contains(obj));
2.1. // 我们尝试把obj再次放入set看看1. // 我们又增加了长度1. set.add(obj);
2. System.out.println(set.size());
3. }
4.1. /**
2. * 专门针对HashSet的测试2。
3. */1. public static void testForHashSet2() {
2. System.out.println("----- testForHashSet2 -----------");
3. HashSet<MyObject2> set = new HashSet<MyObject2>();
4. MyObject2 obj = null;
5. for (int i = 0; i < 3; i++) {
6. obj = new MyObject2("java2000" + i, i);
7. set.add(obj);
8. System.out.println(set.size());
9. }
10. }
11.1.}
2.1.class MyObject {
1. private int age;
2. private String name;
3.1. public int getAge() {
2. return age;
3. }
4.1. public void setAge(int age) {
2. this.age = age;
3. }
4.1. public String getName() {
2. return name;
3. }
4.1. public void setName(String name) {
2. this.name = name;
3. }
4.1. MyObject(String name, int age) {
2. this.name = name;
3. this.age = age;
4. }
5.1. public boolean equals(Object obj) {
2. System.out.println("equals");
3. if (obj == null || !(obj instanceof MyObject)) {
4. return false;
5. }
6. MyObject o = (MyObject) obj;
7. return this.age == o.age && this.name.equals(o.name);
8. }
9.1. public int hashCode() {
2. int hashCode = name.hashCode() + String.valueOf(age).hashCode();
3. return hashCode;
4. }
5.}
6.1.class MyObject2 {
1. private int age;
2. private String name;
3.1. public int getAge() {
2. return age;
3. }
4.1. public void setAge(int age) {
2. this.age = age;
3. }
4.1. public String getName() {
2. return name;
3. }
4.1. public void setName(String name) {
2. this.name = name;
3. }
4.1. MyObject2(String name, int age) {
2. this.name = name;
3. this.age = age;
4. }
5.1. public boolean equals(Object obj) {
2. System.out.println("equals");
3. if (obj == null || !(obj instanceof MyObject2)) {
4. return false;
5. }
6. MyObject2 o = (MyObject2) obj;
7. return this.age == o.age && this.name.equals(o.name);
8. }
9.1. public int hashCode() {
2. return 1;
3. }
4.}
5.1.class MyObject3 {
1. private int age;
2. private String name;
3.1. // 采用一个变量进行控制1. // 一旦生成了hashCode,则不再变动1. private int HASHCODE = Integer.MIN_VALUE;
2.1. public int hashCode() {
2. if (HASHCODE == Integer.MIN_VALUE) {
3. // 重新生成本类的hashCode1. HASHCODE = name.hashCode() + String.valueOf(age).hashCode();
2.1. }
2. return HASHCODE;
3. }
4.}
说明,针对HashSet:
•Set不允许重复
•允许 null,重复的null只算一个
•判断是否存在一个数据(是否重复),先判断其hashCode是否存在,若存在再逐个判断hashCode相同的数据是否相等
•判断是否相等,除了hashCode相等外,还要判断对象引用相等(==),或者 equals
•如果一个对象的hashCode变动了,会造成找不到这个对象,也就出现了内存泄漏的危险。
hashCode 方法是HashSet里面对象的关键,它的算法影响到了数据的分散和查找效率。某个确认对象的hashCode不应该变动,避免出现内存泄漏,可以采用如下方法,来方式属性变化造成hashCode变化
1.class MyObject3 {
2. private int age;
3. private String name;
4.1. // 采用一个变量进行控制1. // 一旦生成了hashCode,则不再变动1. private int HASHCODE = Integer.MIN_VALUE;
2.1. public int hashCode() {
2. if (HASHCODE == Integer.MIN_VALUE) {
3. // 重新生成本类的hashCode1. HASHCODE = name.hashCode() + String.valueOf(age).hashCode();
2.1. }
2. return HASHCODE;
3. }
4.}
1.package collection.lession2;
2.1.import java.util.HashSet;
1.import java.util.Set;
1.1./**
1. *认识Set集合之HashSet。<br>
2. * Set用来保存不允许重复的数据。可以是任何对象类型。<br>
3. * JDK5以后,主类型可以通过autobox 放入Set里面。
4. *
7. */1.public class Lession2 {
2.1. public static void main(String[] args) {
2. // 普通测试1. testNormal();
2.1. // 测试HashSet的特殊性1. testForHashSet();
2. testForHashSet2();
3. }
4.1. /**
2. * 测试保存混合类型的数据.
3. */1. public static void testNormal() {
2. System.out.println("----- testNormal -----------");
3. // Set有多个实现,我们先看看最常用的HashSet1. Set set = new HashSet();
2. // 添加一个字符串1. set.add("字符串");
2. // 添加一个整数对象1. set.add(new Integer(1));
2. // 利用JDK5的特性,增加一个浮点数1. set.add(123.45);
2.1. // 我们看看集合里对象的数量1. System.out.println(set.size());
2.1. // 我们尝试增加一个重复的字符串1. set.add("字符串");
2.1. // 我们再次看看集合里对象的数量1. System.out.println(set.size());
2.1. // 我们来测试看看是否集合里包含了某个数据1. System.out.println(set.contains(123.45));
2.1. // 我们从里面把这个浮点数删除1. set.remove(123.45);
2.1. // 我们再次看看集合里对象的数量1. System.out.println(set.size());
2. }
3.1. /**
2. * 专门针对HashSet的测试。
3. */1. public static void testForHashSet() {
2. System.out.println("----- testForHashSet -----------");
3. HashSet<MyObject> set = new HashSet<MyObject>();
4.1. // 增加一个null对象1. set.add(null);
2. // 我们再次看看集合里对象的数量1. System.out.println(set.size());
2. // 再次增加一个null看看1. set.add(null);
2. // 我们再次看看集合里对象的数量1. System.out.println(set.size());
2.1. MyObject obj = new MyObject("java2000", 2);
2. set.add(obj);
3.1. obj = new MyObject("csdn", 10);
2. set.add(obj);
3.1. // 我们再次看看集合里对象的数量1. System.out.println(set.size());
2.1. // 判断是否包含某个对象1. System.out.println(set.contains(obj));
2.1. obj = new MyObject("java2000_net", 2);
2. set.add(obj);
3.1. // 我们再次看看集合里对象的数量1. System.out.println(set.size());
2.1. // 我们尝试把obj再次放入set看看1. // 并没有增加,因为是重复的1. set.add(obj);
2. System.out.println(set.size());
3.1. // 我们构造一个新的对象,内容和前面的相同1. obj = new MyObject("java2000_net", 2);
2. set.add(obj);
3. System.out.println(set.size());
4.1. // 我们修改一下obj里面的年龄,再看看1. obj.setAge(3);
2.1. // 我们再测试看看是否包含此对象。1. // 请注意,我们这个obj和前面的obj是同一个对象1. // 我们仅仅修改了一下我们的年龄1. System.out.println(set.contains(obj));
2.1. // 我们尝试把obj再次放入set看看1. // 我们又增加了长度1. set.add(obj);
2. System.out.println(set.size());
3. }
4.1. /**
2. * 专门针对HashSet的测试2。
3. */1. public static void testForHashSet2() {
2. System.out.println("----- testForHashSet2 -----------");
3. HashSet<MyObject2> set = new HashSet<MyObject2>();
4. MyObject2 obj = null;
5. for (int i = 0; i < 3; i++) {
6. obj = new MyObject2("java2000" + i, i);
7. set.add(obj);
8. System.out.println(set.size());
9. }
10. }
11.1.}
2.1.class MyObject {
1. private int age;
2. private String name;
3.1. public int getAge() {
2. return age;
3. }
4.1. public void setAge(int age) {
2. this.age = age;
3. }
4.1. public String getName() {
2. return name;
3. }
4.1. public void setName(String name) {
2. this.name = name;
3. }
4.1. MyObject(String name, int age) {
2. this.name = name;
3. this.age = age;
4. }
5.1. public boolean equals(Object obj) {
2. System.out.println("equals");
3. if (obj == null || !(obj instanceof MyObject)) {
4. return false;
5. }
6. MyObject o = (MyObject) obj;
7. return this.age == o.age && this.name.equals(o.name);
8. }
9.1. public int hashCode() {
2. int hashCode = name.hashCode() + String.valueOf(age).hashCode();
3. return hashCode;
4. }
5.}
6.1.class MyObject2 {
1. private int age;
2. private String name;
3.1. public int getAge() {
2. return age;
3. }
4.1. public void setAge(int age) {
2. this.age = age;
3. }
4.1. public String getName() {
2. return name;
3. }
4.1. public void setName(String name) {
2. this.name = name;
3. }
4.1. MyObject2(String name, int age) {
2. this.name = name;
3. this.age = age;
4. }
5.1. public boolean equals(Object obj) {
2. System.out.println("equals");
3. if (obj == null || !(obj instanceof MyObject2)) {
4. return false;
5. }
6. MyObject2 o = (MyObject2) obj;
7. return this.age == o.age && this.name.equals(o.name);
8. }
9.1. public int hashCode() {
2. return 1;
3. }
4.}
5.1.class MyObject3 {
1. private int age;
2. private String name;
3.1. // 采用一个变量进行控制1. // 一旦生成了hashCode,则不再变动1. private int HASHCODE = Integer.MIN_VALUE;
2.1. public int hashCode() {
2. if (HASHCODE == Integer.MIN_VALUE) {
3. // 重新生成本类的hashCode1. HASHCODE = name.hashCode() + String.valueOf(age).hashCode();
2.1. }
2. return HASHCODE;
3. }
4.}
说明,针对HashSet:
•Set不允许重复
•允许 null,重复的null只算一个
•判断是否存在一个数据(是否重复),先判断其hashCode是否存在,若存在再逐个判断hashCode相同的数据是否相等
•判断是否相等,除了hashCode相等外,还要判断对象引用相等(==),或者 equals
•如果一个对象的hashCode变动了,会造成找不到这个对象,也就出现了内存泄漏的危险。
hashCode 方法是HashSet里面对象的关键,它的算法影响到了数据的分散和查找效率。某个确认对象的hashCode不应该变动,避免出现内存泄漏,可以采用如下方法,来方式属性变化造成hashCode变化
1.class MyObject3 {
2. private int age;
3. private String name;
4.1. // 采用一个变量进行控制1. // 一旦生成了hashCode,则不再变动1. private int HASHCODE = Integer.MIN_VALUE;
2.1. public int hashCode() {
2. if (HASHCODE == Integer.MIN_VALUE) {
3. // 重新生成本类的hashCode1. HASHCODE = name.hashCode() + String.valueOf(age).hashCode();
2.1. }
2. return HASHCODE;
3. }
4.}