欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java集合基础语法(Map、HashMap、LinkedHashMap、TreeMap、HashTabel)

程序员文章站 2022-06-28 17:17:45
文章目录Map集合概述和特点Map集合的基本功能Map集合概述和特点查看API可以知道:将键映射到值的对象一个映射不能包含重复的键每个键最多只能映射到一个值Map是双列的,Collection是单列的Map的键唯一,Collection的子体系Set是唯一的Map集合的数据结构针对键有效,跟值无关;Collection集合的数据结构是针对元素有效Map集合的基本功能package demo;//由于键是存在哈希表中,为了保证键的唯一性,如果键的类型时自定义引用数据类型(例如Studen...



Map集合概述和特点

  • 将键映射到值的对象
    一个映射不能包含重复的键
    Map:双列集合,一个键只能映射一个值,键是唯一的,键相同,值覆盖。

  • 某些映射实现可明确保证其顺序,如 TreeMap 类;另一些映射实现则不保证顺序,如 HashMap 类。

  • Map接口中的内部类:
    public static interface Map.Entry<K,V>映射项(键-值对)
    Map.entrySet 方法返回映射的 collection 视图,该方法返回的是的对象能查看每个结点对象的键与值;后面在遇到集合遍历的时候可以很好的理解。

  • Map集合的方法
    Java集合基础语法(Map、HashMap、LinkedHashMap、TreeMap、HashTabel)

  • Map接口的常见的实现类:
    HashMap、TreeMap、Hashtable、LinkedHashMap

HashMap类

HashMap 他的键的数据结构是哈希表,键无序,且唯一。并允许使用 null 值和 null 键。线程不安全,效率高。

1、 在JDK1.8之前,HashMap采用数组+链表实现,即使用链表处理冲突,同一hash值的节点都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。

2、 而JDK1.8中,HashMap采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。

保证键的唯一性:

3.Map类的集合只与键有关,我们可以通过添加元素的方法查看底层的代码;它的底层是调用键对象的equals()和hashCode()方法来保证键的唯一性;与hashSet集合一样,重写hashCode()是为了减少碰撞。由于键是存在哈希表中,为了保证键的唯一性,如果键的类型时自定义引用数据类型(例如Student对象),每一个new的对象地址值不同,那么就会被当做是不同的对象在哈希表均会存储;因此就需要重写Student类的hashcode与equals方法,重写的hashcode根据对象的成员变量值来获取哈希表的地址值,重写的equals方法比较字符串字面值而不是地址值,就可以筛选出两个地址值不同但是成员变量相同的对象,避免重复存储。

HashMap的方法:
Java集合基础语法(Map、HashMap、LinkedHashMap、TreeMap、HashTabel)
举例理解:

public class test { public static void main(String[] args) { HashMap<String, String> hm = new HashMap<>(); //当键相同,值就会覆盖,返回的是上一次这个键所映射的那个旧值。 String s = hm.put("1", "11"); String s1 = hm.put("1", "12"); String s2 = hm.put("2", "13"); String s3 = hm.put("3", "13"); String s4 = hm.put("4", "13"); String s5 = hm.put("5", "13"); String s66 = hm.put(null, null); System.out.println(hm);//{null=null, 1=12, 2=13, 3=13, 4=13, 5=13} //当键相同,值就会覆盖,返回的是上一次这个键所映射的那个旧值。 System.out.println(s);//null System.out.println(s1);//11 System.out.println(s2);//null //清空集合 //hm.clear(); //获取集合的长度 System.out.println(hm.size());//6 //删除一个键,返回的是那个键所对应的值。 String s6 = hm.remove("1"); System.out.println(hm);//{null=null, 2=13, 3=13, 4=13, 5=13} System.out.println(s6);//12 //传入key与value进行删除 返回布尔值 boolean remove = hm.remove("2", "13"); System.out.println(remove); //true //判断集合是否包含键"1" boolean b = hm.containsKey("1"); //判断集合是否包含值 boolean b1 = hm.containsValue("13"); //判断集合是否为空isEmpty() boolean b3 = hm.isEmpty(); //通过键来获取值,没有返回null String s7 = hm.get("2"); //通过键来获取值,没有对应的值,可以给一个默认值。 System.out.println(hm.getOrDefault("1", "no value"));//no value //values();获取所有值的集合 Collection<String> values = hm.values(); System.out.println(values);//[null,13, 13, 13] System.out.println("============================"); // Map 集合的遍历 //第一种:通过键找值的方式来遍历  keySet();获取所有键的集合 Set<String> keySet = hm.keySet(); System.out.println(keySet);//[null,3, 4, 5] for (String key : keySet) { String value = hm.get(key); System.out.println(key + "==" + value); } /*null==null
        3==13
        4==13
        5==13*/ //第二种:把键值对,看做一个对象,把所有键值对,对象获取出来,然后使用键值对,对象中的方法来获取键和值。 Set<Map.Entry<String, String>> entries1 = hm.entrySet(); /*   Map.Entry<String, String>
        K getKey ()
        返回与此项对应的键。
        V getValue ()
        返回与此项对应的值。*/ for (Map.Entry<String, String> stringStringEntry : entries1) { String key = stringStringEntry.getKey(); String value = stringStringEntry.getValue(); System.out.println(key + "==" + value); } /*

        null==null
        3==13
        4==13
        5==13*/ //第三种:JDK1.8 提供的遍历方式forEach()方法 采用匿名内部类的方式重写方法来遍历集合 hm.forEach(new BiConsumer<String, String>() { @Override //传入的就是hm的键与值 public void accept(String key, String value) { System.out.println(key + "==" + value); } }); /*
null==null
3==13
4==13
5==13*/ 

LinkedHashMap类

键的数据结构链表和哈希表。链表保证了键有序,哈希表保证了键唯一。

 LinkedHashMap<String, String> stringStringLinkedHashMap = new LinkedHashMap<>(); stringStringLinkedHashMap.put("1", "100"); stringStringLinkedHashMap.put("6", "100"); stringStringLinkedHashMap.put("3", "100"); stringStringLinkedHashMap.put("2", "100"); stringStringLinkedHashMap.put("41", "100"); stringStringLinkedHashMap.put("4", "100"); System.out.println(stringStringLinkedHashMap);//{1=100, 6=100, 3=100, 2=100, 41=100, 4=100} 

TreeMap类

TreeMap:
键的数据结构是红黑树, 可保证键的排序和唯一性,线程是不安全的效率比较高

 // 排序分为自然排序和比较器排序 //空参构造,就使用的自然排序。 //自然排序,他对键的要求是,要求键实现Comparable接口,重写  compareTo方法,根据此方法的返回值的正负0 来决定键的排列顺序 //自然排序 //Integer类型的键 默认实现了Comparable接口,因此不需要手动重写就可以对键排序 TreeMap<Integer, String> integerStringTreeMap = new TreeMap<>(); integerStringTreeMap.put(10, "a"); integerStringTreeMap.put(11, "a"); integerStringTreeMap.put(14, "a"); integerStringTreeMap.put(70, "a"); System.out.println(integerStringTreeMap);//{10=a, 11=a, 14=a, 70=a} //自定义一个学生类,需要重写Comparable接口,才可以对于学生对象进行排序 //重写的方法是按照学生姓名长度来排序: TreeMap<Student, String> hm1 = new TreeMap<>(); hm1.put(new Student("张三", 23), "s002"); hm1.put(new Student("李四", 24), "s003"); hm1.put(new Student("王五", 25), "s004"); hm1.put(new Student("赵六", 20), "s005"); System.out.println(hm1); //{Student{name='张三', age=23}=s002, Student{name='李四', age=24}=s003, Student{name='王五', age=25}=s004, Student{name='赵六', age=20}=s005} //使用比较器排序,根据年龄大小排序 TreeMap<Student, String> hm3 = new TreeMap<>(new Comparator<Student>() { @Override public int compare(Student a, Student b) { int num = a.getAge() - b.getAge(); int num1 = num == 0 ? a.getName().compareTo(b.getName()) : num; return num1; } }); hm3.put(new Student("张三", 23), "s002"); hm3.put(new Student("李四", 24), "s003"); hm3.put(new Student("王五", 25), "s004"); hm3.put(new Student("赵六", 20), "s005"); System.out.println(hm3); //{Student{name='赵六', age=20}=s005, Student{name='张三', age=23}=s002, Student{name='李四', age=24}=s003, Student{name='王五', age=25}=s004} 

Hashtable类

不允许存储null值和null键 线程安全效率低

 Hashtable<Object, Object> objectObjectHashtable = new Hashtable<>(); // objectObjectHashtable.put(null,"abc");不允许键或者值 为 null 

集合的嵌套练习

 //练习: /* 统计字符串中每个字符出现的次数:“aababcabcdabcde”,获取字符串中每一个字母出现的次数要求结果:
        a(5)b(4)c(3)d(2)e(1)*/ //分析:使用键值对集合存储,键是字符,值是次数 String str = "aababcabcdabcde"; HashMap<Character, Integer> characterIntegerHashMap = new HashMap<>(); //遍历字符串中的元素,如果没有遍历的字符就存入,并先设置次数为1;如果已经存在遍历的元素,就在value值的基础上加1,并重新存储覆盖原key值。 for (int i = 0; i < str.length(); i++) { if (!characterIntegerHashMap.containsKey(str.charAt(i))) { characterIntegerHashMap.put(str.charAt(i), 1); } else { Integer integer = characterIntegerHashMap.get(str.charAt(i)); integer++; characterIntegerHashMap.put(str.charAt(i), integer); } } Set<Map.Entry<Character, Integer>> entries = characterIntegerHashMap.entrySet(); for (Map.Entry<Character, Integer> entry : entries) { System.out.print(entry.getKey() + "(" + entry.getValue() + ")"); } //a(5)b(4)c(3)d(2)e(1) 
 /*
          基础班
            张三 20
            李四 22
          就业班
            王五 21
            赵六 23

            集合嵌套之HashMap嵌套HashMap
            */ HashMap<String, Integer> jcMap = new HashMap<>(); jcMap.put("张三",20); jcMap.put("李四", 22); HashMap<String, Integer> jyMap = new HashMap<>(); jyMap.put("王五", 21); jyMap.put("赵六", 23); HashMap<String, HashMap<String, Integer>> maxMap = new HashMap<>(); maxMap.put("基础班",jcMap); maxMap.put("就业班",jyMap); //遍历集合 Set<Map.Entry<String, HashMap<String, Integer>>> entries2 = maxMap.entrySet(); for (Map.Entry<String, HashMap<String, Integer>> stringHashMapEntry : entries2) { System.out.println(stringHashMapEntry.getKey()); Set<Map.Entry<String, Integer>> entries3 = stringHashMapEntry.getValue().entrySet(); for (Map.Entry<String, Integer> stringIntegerEntry : entries3) { System.out.println("\t"+stringIntegerEntry.getKey() + " " + stringIntegerEntry.getValue()); } System.out.println(); } 
 /*
     三国演义
	 	吕布
	 	周瑜
	 笑傲江湖
	 	令狐冲
	 	林平之
	 神雕侠侣
	 	郭靖
	 	杨过

        Map 集合 嵌套List集合
        * */ ArrayList<String> sgList = new ArrayList<>(); sgList.add("吕布"); sgList.add("周瑜"); ArrayList<String> xaList = new ArrayList<>(); xaList.add("令狐冲"); xaList.add("林平之"); ArrayList<String> sdList = new ArrayList<>(); sdList.add("郭靖"); sdList.add("杨过"); HashMap<String, ArrayList<String>> bigMap = new HashMap<>(); bigMap.put("三国演义",sgList); bigMap.put("笑傲江湖", xaList); bigMap.put("神雕侠侣", sdList); Set<Map.Entry<String, ArrayList<String>>> entries3 = bigMap.entrySet(); for (Map.Entry<String, ArrayList<String>> stringArrayListEntry : entries3) { System.out.println(stringArrayListEntry.getKey()); ArrayList<String> value = stringArrayListEntry.getValue(); for (String s8 : value) { System.out.println(s8); } System.out.println(); } 
 /* A:
        案例演示
                集合嵌套之ArrayList嵌套HashMap
        假设ArrayList集合的元素是HashMap。有3个。
        每一个HashMap集合的键和值都是字符串。

        周瑜-- - 小乔
        吕布-- - 貂蝉

        郭靖-- - 黄蓉
        杨过-- - 小龙女

        令狐冲-- - 任盈盈
        林平之-- - 岳灵珊*/ HashMap<String, String> sgMap = new HashMap<>(); sgMap.put("周瑜","小乔"); sgMap.put("吕布", "貂蝉"); HashMap<String, String> sdMap = new HashMap<>(); sdMap.put("郭靖", "黄蓉"); sdMap.put("杨过", "小龙女"); HashMap<String, String> xaMap = new HashMap<>(); xaMap.put("令狐冲", "任盈盈"); xaMap.put("林平之", "岳灵珊"); ArrayList<HashMap<String, String>> bigList = new ArrayList<>(); bigList.add(sgMap); bigList.add(sdMap); bigList.add(xaMap); //遍历集合 for (HashMap<String, String> stringStringHashMap : bigList) { Set<Map.Entry<String, String>> entries4 = stringStringHashMap.entrySet(); for (Map.Entry<String, String> stringStringEntry : entries4) { System.out.println(stringStringEntry.getKey() + "---" + stringStringEntry.getValue()); } System.out.println(); } 

工具类Collections

Java针对 Collection 集合,提供了一个工具类Collections 为了方便的去操作 Collection 集合

Collections成员方法

public static void sort (List < T > list):排序, 默认按照自然顺序
public static int binarySearch (List < ? > list, T key):二分查找 前提 元素有序
public static T max(Collection < ? > coll):获取最大值
public static T min(Collection < ? > coll):获取最小值
public static void reverse (List < ? > list):反转
public static void shuffle (List < ? > list):随机置换

 ArrayList<Integer> list = new ArrayList<>(); list.add(20); list.add(100); list.add(203); list.add(20333); list.add(2014); Collections.sort(list); System.out.println(list);//[20, 100, 203, 2014, 20333] //可以重写排序比较器 自定义排序方式 /*Collections.sort(list, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return 0;
            }
        });*/ System.out.println(Collections.binarySearch(list, 200000)); System.out.println(Collections.max(list));//20333 System.out.println(Collections.min(list));//20 Collections.reverse(list); Collections.shuffle(list); System.out.println(list);//[20333, 20, 100, 2014, 203] 
 //先创建一个集合充当牌盒子 ArrayList<String> pokerBox = new ArrayList<>(); //生成54张牌放进牌盒子 String[] colors={"♠","♥","♦","♣"}; String[] nums={"A","2","3","4","5","6","7","8","9","10","J","Q","K"}; for (String color : colors) { for (String num : nums) { String poker = color.concat(num); pokerBox.add(poker); } } //手动添加大小王 pokerBox.add("☀"); pokerBox.add("☼"); //洗牌 Collections.shuffle(pokerBox); //发牌:得有三个人来斗地主,还得留三张底牌 ArrayList<String> 星仔 = new ArrayList<>(); ArrayList<String> 刀仔 = new ArrayList<>(); ArrayList<String> 高进 = new ArrayList<>(); ArrayList<String> 底牌 = new ArrayList<>(); //发牌方式1: 一人数个10来张发给你 /*List<String> strings = pokerBox.subList(0, 11);
        for (String string : strings) {
            星仔.add(string);
        }*/ // 方式2:传统发牌 一人一张转着发 //用牌的索引对3取余 /*  星仔 0 3 6 9   余数 0
        刀仔 1 4 7 10  余数 1
        高进 2 5 8  11  余数 2 */ for (int i = 0; i < pokerBox.size(); i++) { if(i>=pokerBox.size()-3){ 底牌.add(pokerBox.get(i)); }else if(i%3==0){ 星仔.add(pokerBox.get(i)); } else if (i % 3 == 1) { 刀仔.add(pokerBox.get(i)); }else{ 高进.add(pokerBox.get(i)); } } //看牌 System.out.println(星仔); 

斗地主排序版,牌发好之后,从小到大排好

 /*分析思路:
* 使用HashMap存储牌与对应的索引,此时牌的顺序已经存储完成
* 将索引放入一个ArrayList中,并打乱顺序发给三个人
* 三个人使用TreeSet存储索引,完成自动排序
* */ HashMap<Integer, String> box = new HashMap<>(); ArrayList<String> poker = new ArrayList<>(); //生成54张牌放进牌盒子 String[] colorss={"♠","♥","♦","♣"}; String[] numss={"A","2","3","4","5","6","7","8","9","10","J","Q","K"}; for (String numss1 : numss) { for (String colorss1 : colorss) { String concat = colorss1.concat(numss1); poker.add(concat); } } //手动添加大小王 poker.add("☀"); poker.add("☼"); //生成索引与牌的Map集合 for (int i = 0; i < 54; i++) { box.put(i,poker.get(i)); } //生成三个TreeSet 接收索引 TreeSet<Integer> one = new TreeSet<>(); TreeSet<Integer> two = new TreeSet<>(); TreeSet<Integer> three = new TreeSet<>(); TreeSet<Integer> four = new TreeSet<>(); ArrayList<TreeSet<Integer>> treeSets = new ArrayList<>(); treeSets.add(four); treeSets.add(one); treeSets.add(two); treeSets.add(three); //将索引放入一个集合中 ArrayList<Integer> integers = new ArrayList<>(); for (int i = 0; i < 54; i++) { integers.add(i); } //洗牌 Collections.shuffle(integers); //根据索引发牌 for (Integer integer : integers) { if (integer>= 51) { four.add(integers.get(integer)); } else if (integer % 3 == 0) { one.add(integers.get(integer)); } else if (integer % 3 == 1) { two.add(integers.get(integer)); } else { three.add(integers.get(integer)); } } //根据索引查看对应的牌 for (TreeSet<Integer> treeSet : treeSets) { for (Integer integer : treeSet) { String s8 = box.get(integer); System.out.print(s8+" "); } System.out.println(); } } } 

本文地址:https://blog.csdn.net/qq_44241861/article/details/107881097

相关标签: Java基础