1.HashMap地层是基于HashCode表 来给每个数据给定一个HashCode码,(可以理解为地址值, ), 但是HashMap遍历出来的是无须的, 因为遍历时是通过HashCode码值来遍历的
HashMap地层是重写了equal方法, 所以保证了键的唯一性, 如果有重复的键, 后面的顶掉前面的,(也相当于将后面出现的键值对的值赋给了前面)
HashMap的值如果是自定义对象,则要在自定义对象中重写euqal 和HashCode, 不然会出现键重复(原因: 每个自定义的对象都有自己的地址值, HashMap在对比存储时,会将地址值进行对比, 所以出现键重复 因为不同的对象地址值永远不会相同)
HashMap的键唯一,但是值不唯一
HashMap<student, Integer> hmap=new HashMap<>(); student s1=new student("张三",12); student s2=new student("李四",14); student s3=new student("王五",13); student s4=new student("张三",12); student s5=new student("张三",18); hmap.put(s1, 18001); hmap.put(s2, 18002); hmap.put(s3, 18003); hmap.put(s4, 18004); hmap.put(s5, 18005); Set<student> set = hmap.keySet(); for(student s:set) { Integer i = hmap.get(s); System.out.println(s.getName()+s.getAge()+" "+i); }//student不重写Hash的equal方法的输出结果:
//李四14 18002
//王五13 18003
//张三12 18001
//张三18 18005
//张三12 18004
//student重写Hash的equal方法的输出结果:
//王五13 18003
//张三18 18005
//张三12 18004
//李四14 18002
//原因:hashmap的排序要实现地层hash和equal两个方法,但是默认系统类地层已经给出
//所以使用HashMap码系统会自动通过hashMap码值进行排序
//但在自定义类中,必须自己重写这两个方法才能实现去重和Hash码表排序的功能
2. Hashtable
Hashtable集合线程安全的类,同步,执行效率低,但是不允许键或值出现null
HashMap集合线程不安全的类,不同步,执行效率高(允许键和值是null的)
Hashtable<Integer, Integer> htable=new Hashtable<>(); htable.put(11, 11); htable.put(null, 11); //报错 无法输出 htable.put(12, null); //报错 无法输出 Set<Integer> set1 = htable.keySet(); for(Integer i:set1) { Integer integer = hmap.get(i); System.out.println(i+" "+integer); }
3.LinkedHashMap
LinkedHashMap 是HashMap的一个子类,保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.也可以在构造时用带参数,按照应用次数排序。
在遍历的时候会比HashMap慢,不过有种情况例外,当HashMap容量很大,实际数据较少时,遍历起来可能会比 LinkedHashMap慢,因为LinkedHashMap的遍历速度只和实际数据有关,和容量无关,而HashMap的遍历速度和他的容量有关。
//LinkedHashMap遵循的是存储和取出一致,同时因为继承与Map接口,所以保证了键的唯一性 public class LinkedHashMap1 { public static void main(String[] args) { LinkedHashMap<Integer, String> lhmap=new LinkedHashMap<>(); lhmap.put(11, "a"); lhmap.put(12, "b"); lhmap.put(13, "c"); lhmap.put(14, "d"); lhmap.put(11, "e"); Set<Integer> set = lhmap.keySet(); for(Integer i:set) { String string = lhmap.get(i); System.out.println(i+" "+string); }
输出结果:
11 e
12 b
13 c
14 d
实现了键的唯一性. 且后面出现的键顶替前面的
4.TreeMap
TreeMap的键相当于TreeSet,所以键如果是int类型,则会按照红黑数列排序
如果不是int类型,则会按照HashCode码排序(无序的)
public class TreeMap1 { public static void main(String[] args) { TreeMap<String, String> tmap=new TreeMap<>(); tmap.put("hello", "张三"); tmap.put("yes", "李四"); tmap.put("no", "王五"); tmap.put("hi", "张三");//键不同值相同,不删除 tmap.put("hello", "周六");//键相同值不同,顶替掉前一个键相同的值 //因为遵循Map接口 Set<String> set = tmap.keySet(); for(String s:set){ String string = tmap.get(s); System.out.println(s+"\t"+string); }
输出结果: hello 周六 hi 张三 no 王五 yes 李四
4.Collections工具类
Collections 此类完全由在 collection 上进行操作或返回 collection 的静态方法组成。
Collection和Collections的区别:
Collection:顶层次单列集合的根接口,它是一个集合,是一个接口
Collections:是针对集合操作的工具类,有一些功能:随机置换,集合里面的二分查找,将集合的元素进行反转
二分查找法 和 shuffle方法
//建立集合 List<Integer> arr=new ArrayList<Integer>(); //给集合中添加元素 arr.add(13); arr.add(23); arr.add(34); arr.add(45); arr.add(56); arr.add(67); arr.add(78); //增强for循环 for(Integer i:arr) { System.out.println(i); } // public static <T> int binarySearch(List<T> list, T key)二分搜索法 System.out.println(Collections.binarySearch(arr, 23)); //输出接果为该数据所在的集合位置(二分法的前提必须集合有序) //static T max(Collection coll):获取集合中的最大值 System.out.println(Collections.max(arr)); //输出接过为:78 // public static void reverse(List<?> list):将集合中的元素顺序反转(无返回类型) Collections.reverse(arr); System.out.println(arr); //[78, 67, 56, 45, 34, 23, 13] //public static void shuffle(List<?> list):将集合中的元素打乱(无返回类型) Collections.shuffle(arr); System.out.println(arr); //[56, 78, 67, 34, 23, 45, 13]每次随机的结果不一样