哈希表有两种形式
HashSet和HashMap
HashSet只有key,HashMap中有key和value。结构都是一样的,没有区别。
public static void main(String[] args) {
HashSet<Integer> hashSet1 = new HashSet<>();
hashSet1.add(2);
System.out.println(hashSet1.contains(2));
hashSet1.add(new Integer(3));
System.out.println(hashSet1.contains(3));
hashSet1.remove(2);
System.out.println(hashSet1.contains(2));
HashMap<Integer,String> map = new HashMap<>();
map.put(1, "yf");
map.put(1,"yf1");//put方法既是新增也是更新。
map.put(2, "yf2");
System.out.println(map.containsKey(1));
System.out.println(map.get(1));
System.out.println(map.get(4));
}
重要的是哈希表中增删改查的时间都是常数级别的,和数据量没有关系。但是这个常数时间比较大。
如果是基础数据类型,哈希表内部是按照值传递,就是将put进哈希表中的数据拷贝一份。
如果是自定义类,哈希表内部是按照应用传递,拷贝的是put进哈希表对象的地址。一律只占八字节。
有序表
TreeSet和TreeMap
有序表要求Key一定是可以比较的,
有序表Tree比哈希表性能要差点,是logN级别的,但是也很优秀了。
放入有序表中的基本类型是值传递
放入有序表中的不是基础类型就需要定义比较器,内部按照引用传递。
例如
public static class Node{
public int value;
public Node next;
public Node(int value) {
this.value = value;
}
}
public static void main(String[] args) {
Node nodeA = new Node(1);
Node nodeB = new Node(2);
Node nodeC = new Node(3);
TreeSet<Node> set = new TreeSet<>();
try {
set.add(nodeA);
set.add(nodeB);
System.out.println("success");
}catch(Exception e) {
e.printStackTrace();
}
}
这样的代码由于没有提供比较器,是一定会报异常的。
public class Day09 {
public static class Node{
public int value;
public Node next;
public Node(int value) {
this.value = value;
}
}
public static class NodeComp implements Comparator<Node>{
@Override
public int compare(Node o1, Node o2) {
// TODO Auto-generated method stub
return o1.value-o2.value;
}
}
public static void main(String[] args) {
Node nodeA = new Node(1);
Node nodeB = new Node(2);
Node nodeC = new Node(3);
TreeSet<Node> set = new TreeSet<>(new NodeComp());
try {
set.add(nodeA);
set.add(nodeB);
System.out.println("success");
}catch(Exception e) {
e.printStackTrace();
}
}
}
加入比较器之后就不会再报异常了