随着Java学习的深入,感觉大一时搞了一年的ACM,简直是明智之举,Java里非常多数据结构、算法类的东西,理解起来就轻松多了
Set集合下有两大子类开发经常使用 HashSet集合 、TreeSet集合
Set集合的元素是不反复且无序
一、HashSet集合
API文档解释:此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。
它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类同意使用null 元素。
此类为基本操作提供了稳定性能,注意。此实现不是同步的。
由上能够总结出:HashSet集合的方法:内部数据结构是哈希表,且不同步,不管反复元素有多少。仅仅存一个。
import java.util.HashSet; import java.util.Iterator; public class Main { public static void main(String[] args) { HashSet hash = new HashSet(); hash.add("123"); hash.add("456"); hash.add("asd"); hash.add("789"); Iterator it = hash.iterator(); while(it.hasNext()){ System.out.println(it.next()); } } }
哈希表
数据经过哈希算法存储,会经过两次推断,第一此推断位置。第二次会推断内容。比方“ab”已经存储了,“ba”经过算法得到的位置是“ab”的位置,这时要经过第二次推断,确定内容是否同样。不同样会通过过算法得到新的位置,ACM里通常会经过线性探測再散列或者是链地址法
总结
哈希表推断元素是否同样:
1.推断的是两个元素的哈希值是否同样,假设同样,再推断两个对象的内容是否同样
2.推断哈希值同样。HashCode方法(返回此字符串的哈希码)。推断内容同样。equals方法
注:哈希值不同,就不须要第二次推断内容是否同样
哈希表演示
import java.util.HashSet; import java.util.Iterator; class Man extends Object//必须继承Object类才干复写HshCode,equals { private String name; private int age; public Man() { super(); // TODO Auto-generated constructor stub } public Man(String name, int age) { super(); this.name = name; //System.out.println("1号"+this); this.age = age; } @Override public int hashCode() { final int prim = 31; //System.out.println("namecode = "+name.hashCode()); return name.hashCode()+age*prim; } @Override public boolean equals(Object obj) { if(this == obj) return true; //System.out.println("2号"+this); if(!(obj instanceof Man)) throw new ClassCastException("类型错误"); Man m = (Man)obj; return this.name.equals(m.name) && this.age == m.age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } public class Main { public static void main(String[] args) { HashSet hash = new HashSet(); hash.add(new Man("a",11)); hash.add(new Man("b",12)); hash.add(new Man("c",13)); hash.add(new Man("a",11)); Iterator it = hash.iterator(); while(it.hasNext()){ Man M = (Man)it.next(); System.out.println(M.getName()+"....."+M.getAge()); } } }
特别注意:上述代码的1号和2号两个this,代表的对象不同,不能混淆
练习
关于ArrayList的演示
import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; class Man extends Object { private String name; private int age; public Man() { super(); // TODO Auto-generated constructor stub } public Man(String name, int age) { super(); this.name = name; this.age = age; } @Override public boolean equals(Object obj) { if(this == obj) return true; if(!(obj instanceof Man)) throw new ClassCastException("类型错误"); Man m = (Man)obj; return this.name.equals(m.name) && this.age == m.age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } public class Main { public static void main(String[] args) { ArrayList AL = new ArrayList(); AL.add(new Man("a",11)); AL.add(new Man("b",12)); AL.add(new Man("c",13)); AL.add(new Man("a",11)); printf(AL); AL = ArrayListHashDemo(AL); printf(AL); System.out.println(AL.remove(new Man("a",11))); printf(AL); } public static ArrayList ArrayListHashDemo(ArrayList al) { ArrayList temp = new ArrayList(); Iterator it = al.iterator(); while(it.hasNext()) { Object obj = it.next(); if(!temp.contains(obj)) temp.add(obj); } return temp; } public static void printf(ArrayList al) { Iterator it = al.iterator(); while(it.hasNext()) { Man man = (Man)it.next(); System.out.print(man.getName()+".."+man.getAge()+","); } System.out.printf(" "); } }
API文档关于contains的解释:假设列表包括指定的元素。则返回 true。更确切地讲,当且仅当列表包括满足(o==null ?
e==null : o.equals(e)) 的元素e 时才返回true。
所以对于ArrayList集合,contains的推断与equals有关,而HashSet与HashCode和equals有关
System.out.println(AL.remove(new Man("a",11)));//同理。remove也是有equals有关,仅仅推断内容