java之集合(详细-Map,Set,List)

news2024/12/15 23:16:13

1集合体系概述

1.1集合的概念

集合是一种容器,用来装数据的,类似于数组,但集合的大小可变,开发中也非常常用。

1.2集合分类

集合分为单列集合和多列集合

Collection代表单列集合,每个元素(数据)只包含一个值

Map代表双列集合,每个元素包含两个值(键值对)。 

1.3Colleection集合体系

Collection集合特点

List系列集合:添加的元素是有序、可重复、有索引

  1. ArrayList、LinekdList :有序、可重复、有索引。

Set系列集合:添加的元素是无序、不重复、无索引。

  1. HashSet: 无序、不重复、无索引;
  2. LinkedHashSet: 有序(先添加的再前面,后添加的再后面)、不重复、无索引。
  3. TreeSet:按照大小默认升序排序、不重复、无索引。 

1.4Map集合体系

 Map集合体系的特点

注意:Map系列集合的特点都是由键决定的,值只是一个附属品,值是不做要求的

  • HashMap(由键决定特点): 无序、不重复、无索引;  (用的最多)
  • LinkedHashMap (由键决定特点):由键决定的特点:有序(先添加的再前面,后添加的再后面)、不重复、无索引。
  • TreeMap (由键决定特点):按照大小默认升序排序、不重复、无索引。

2.Collection集合

2.1 Collection的常用方法

为啥要先学Collection的常用方法?

Collection是单列集合的祖宗,它规定的方法(功能)是全部单列集合都会继承的。

 举例说明:

package com.test.可删;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class Test {
    public static void main(String[] args) {
        Collection<String> c = new ArrayList<>(); // 多态写法
        // 1.public boolean add(E e):添加元素, 添加成功返回true。
        c.add("java1");
        c.add("java1");
        c.add("java2");
        c.add("java2");
        c.add("java3");
        System.out.println(c);//[java1, java1, java2, java2, java3]
        // 2.public boolean isEmpty():判断集合是否为空 是空返回true,反之。
        System.out.println(c.isEmpty()); // false
        // 3.public int size():获取集合的大小。
        System.out.println(c.size());//5
        // 4.public boolean contains(Object obj):判断集合中是否包含某个元素。
        System.out.println(c.contains("java1")); // true
        System.out.println(c.contains("Java1")); // false
        // 5.public boolean remove(E e):删除某个元素:如果有多个重复元素默认删除前面的第一个!
        System.out.println(c.remove("java1"));//true
        System.out.println(c);//[java1, java2, java2, java3]
        // 6.public Object[] toArray():把集合转换成数组
        Object[] arr = c.toArray();
        System.out.println(Arrays.toString(arr));//[java1, java2, java2, java3]
        // 7.public void clear():清空集合的元素。
        c.clear();
        System.out.println(c);//[]
    }
}
扩展:把一个集合的全部数据倒入到另一个集合中去
package com.test.可删;
import java.util.ArrayList;
import java.util.Collection;
public class Test {
    public static void main(String[] args) {
        // 把一个集合的全部数据倒入到另一个集合中去。
        Collection<String> c1 = new ArrayList<>();
        c1.add("java1");
        c1.add("java2");
        Collection<String> c2 = new ArrayList<>();
        c2.add("java3");
        c2.add("java4");
        c1.addAll(c2); // 就是把c2集合的全部数据倒入到c1集合中去。
        System.out.println(c1);//[java1, java2, java3, java4]
        System.out.println(c2);//[java3, java4]
    }
}

2.2Collection的遍历方式

2.2.1迭代器

迭代器概述

迭代器是用来遍历集合的专用方式(数组没有迭代器),在Java中迭代器的代表是Iterator

Collection集合获取迭代器的方法

Iterator迭代器中的常用方法

举例

package com.test.可删;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Test {
    public static void main(String[] args) {
        Collection<String> c = new ArrayList<>();
        c.add("赵敏");
        c.add("小昭");
        c.add("素素");
         c.add("灭绝");
        System.out.println(c);
        // c = [赵敏, 小昭, 素素,灭绝]
        // 使用迭代器遍历集合
        // 1、从集合对象中获取迭代器对象-手动一个一个取。
        Iterator<String> it = c.iterator();
//        System.out.println(it.next());//赵敏
//        System.out.println(it.next());//小昭
//        System.out.println(it.next());//素素
//        System.out.println(it.next());//灭绝
        // System.out.println(it.next()); // 出现异常的

        // 2、我们应该使用循环结合迭代器遍历集合。
        while (it.hasNext()){
            String ele = it.next();
            System.out.println(ele);
        }
    }
}

2.2.2增强for

  • 增强for可以用来遍历集合或者数组。
  • 增强for遍历集合,本质就是迭代器遍历集合的简化写法。 
package com.test.可删;
import java.util.ArrayList;
import java.util.Collection;
public class Test {
    public static void main(String[] args) {
        Collection<String> c = new ArrayList<>();
        c.add("赵敏");
        c.add("小昭");
        c.add("素素");
        c.add("灭绝");
        System.out.println(c);
        // c = [赵敏, 小昭, 素素, 灭绝]
        // 使用增强for遍历集合或者数组。
        for (String ele : c) {
            System.out.println(ele);
        }
        String[] names = {"迪丽热巴", "古力娜扎", "稀奇哈哈"};
        //数组的增强for循环
        for (String name : names) {
            System.out.println(name);
        }
    }
}

2.2.3Lambda表达式

Lambda表达式遍历集合

  • 得益于JDK 8开始的新技术Lambda表达式,提供了一种更简单、更直接的方式来遍历集合。

需要使用Collection的如下方法来完成

package com.test.可删;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;
public class Test {
    public static void main(String[] args) {
        Collection<String> c = new ArrayList<>();
        c.add("赵敏");
        c.add("小昭");
        c.add("殷素素");
        c.add("周芷若");
        System.out.println(c);
        // [赵敏, 小昭, 殷素素, 周芷若]
        // default void forEach(Consumer<? super T> action):  结合Lambda表达式遍历集合:
        c.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
        //简化
        c.forEach((String s) -> {
                System.out.println(s);
        });
        //简化
        c.forEach(s  -> {
            System.out.println(s);
        });
        //简化
        c.forEach(s  -> System.out.println(s) );
        //最终简化表达式
        c.forEach(System.out::println );
    }
}

2.3List集合

List系列集合特点:   有序,可重复,有索引  

  • ArrayList:有序,可重复,有索引。  
  • LinkedList:有序,可重复,有索引。

2.3.1List集合的特有方法

List集合因为支持索引,所以多了很多与索引相关的方法,当然,Collection的功能List也都继承了。

package com.test.可删;
import java.util.ArrayList;
import java.util.List;
public class Test {
    public static void main(String[] args) {
        // 1.创建一个ArrayList集合对象(有序、可重复、有索引)
        List<String> list = new ArrayList<>();  // 一行经典代码
        list.add("蜘蛛精");
        list.add("至尊宝");
        list.add("至尊宝");
        list.add("牛夫人");
        System.out.println(list); // [蜘蛛精, 至尊宝, 至尊宝, 牛夫人]
        // 2.public void add(int index, E element): 在某个索引位置插入元素。
        list.add(2, "紫霞仙子");
        System.out.println(list);//[蜘蛛精, 至尊宝, 紫霞仙子, 至尊宝, 牛夫人]
        // 3.public E remove(int index): 根据索引删除元素,返回被删除元素
        System.out.println(list.remove(2));//紫霞仙子
        System.out.println(list);//[蜘蛛精, 至尊宝, 至尊宝, 牛夫人]
        // 4.public E get(int index): 返回集合中指定位置的元素。
        System.out.println(list.get(3));//牛夫人
        // 5.public E set(int index, E element): 修改索引位置处的元素,修改成功后,会返回原来的数据
        System.out.println(list.set(3, "牛魔王"));//牛夫人
        System.out.println(list);//[蜘蛛精, 至尊宝, 至尊宝, 牛魔王]
    }
}

2.3.2List集合支持的遍历方式

  1. for循环(因为List集合有索引)
  2. 迭代器
  3. 增强for循环
  4. Lambda表达式

 第2,3,4的遍历方式,如有不清楚,见2.2小节

package com.test.可删;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Test {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("糖宝宝");
        list.add("蜘蛛精");
        list.add("至尊宝");
        //(1)for循环
        for (int i = 0; i < list.size(); i++) {
            // i = 0 1 2
            String s = list.get(i);
            System.out.println(s);
        }
        //(2)迭代器。
        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
        //(3)增强for循环(foreach遍历)
        for (String s : list) {
            System.out.println(s);
        }
        //(4)JDK 1.8开始之后的Lambda表达式
        list.forEach(s -> {
            System.out.println(s);
        });
    }
}

2.3.3ArrayList集合

2.3.3.1ArrayList集合的底层原理

2.3.3.2ArrayList集合适合和不适合的应用场景
  1. ArrayList适合:根据索引查询数据,比如根据随机索引取数据(高效)!或者数据量不是很大时!
  2. ArrayList不适合:数据量大的同时又要频繁的进行增删操作!

2.3.4LinkedList集合

2.3.4.1 LinkedList集合的底层原理
  • 基于双链表实现的。
  • 特点:查询慢,增删相对较快,但对首尾元素进行增删改查的速度是极快的。

LinkedList新增了:很多首尾操作的特有方法。

2.3.4.2LinkedList的应用场景

LinkedList的应用场景之一:可以用来设计队列(先进先出,后进后出)(只是在首尾增删元素,用LinkedList来实现很合适!)

LinkedList的应用场景之一:可以用来设计栈(先进后出,后进先出)(只是在首部增删元素,用LinkedList来实现很合适!)

package com.test.可删;
import java.util.LinkedList;
public class Test {
    public static void main(String[] args) {
        // 1、创建一个队列。
        LinkedList<String> queue = new LinkedList<>();
        // 入队
        queue.addLast("第1号人");
        queue.addLast("第2号人");
        queue.addLast("第3号人");
        queue.addLast("第4号人");
        System.out.println(queue);//[第1号人, 第2号人, 第3号人, 第4号人]
        // 出队
        System.out.println(queue.removeFirst());//第1号人
        System.out.println(queue.removeFirst());//第2号人
        System.out.println(queue.removeFirst());//第3号人
        System.out.println(queue);//[第4号人]
        System.out.println("--------------------------------------------------");
        // 2、创建一个栈对象。
        LinkedList<String> stack = new LinkedList<>();
        // 压栈(push)
        stack.push("第1颗子弹");
        stack.push("第2颗子弹");
        stack.push("第3颗子弹");
        stack.push("第4颗子弹");
        System.out.println(stack);//[第4颗子弹, 第3颗子弹, 第2颗子弹, 第1颗子弹]
        // 出栈(pop)
        System.out.println(stack.pop());//第4颗子弹
        System.out.println(stack.pop());//第3颗子弹
        System.out.println(stack);//[第2颗子弹, 第1颗子弹]
    }
}

2.4Set集合

Set系列集合特点:无序:添加数据的顺序和获取出的数据顺序不一致;  不重复; 无索引; 

  • HashSet : 无序、不重复、无索引。
  • LinkedHashSet:有序、不重复、无索引。
  • TreeSet:排序、不重复、无索引。

注意: Set要用到的常用方法,基本上就是Collection提供的!! 自己几乎没有额外新增一些常用功能! 

2.4.1HashSet集合

2.4.1.1哈希值

注意:在正式了解HashSet集合的底层原理前,我们需要先搞清楚一个前置知识:哈希值!

哈希值

  • 就是一个int类型的数值,Java中每个对象都有一个哈希值。
  • Java中的所有对象,都可以调用Obejct类提供的hashCode方法,返回该对象自己的哈希值。

public int hashCode():返回对象的哈希码值。 

对象哈希值的特点 

  • 同一个对象多次调用hashCode()方法返回的哈希值是相同的。
  • 不同的对象,它们的哈希值一般不相同,但也有可能会相同(哈希碰撞)

2.4.1.2HashSet集合的底层原理
  • 基于哈希表实现。
  • 哈希表是一种增删改查数据,性能都较好的数据结构。

哈希表

JDK8之前,哈希表 = 数组+链表

JDK8开始,哈希表 = 数组+链表+红黑树

2.4.1.3两个内容一样的对象,如何让HashSet集合去重

自定义的类型的对象,比如两个内容一样的学生对象,如果让HashSet集合能够去重复! 

结论:如果希望Set集合认为2个内容一样的对象是重复的, 必须重写对象的hashCode()和equals()方法

具体的实现:

java集合篇之练习题(List,Map等的应用练习)-CSDN博客

2.4.1.4LinkedHashSet集合的底层原理

LinkedHashSet:有序(添加和获取元素的顺序是一致的)、不重复、无索引。

LinkedHashSet集合的底层原理:依然是基于哈希表(数组、链表、红黑树)实现的。

但是,它的每个元素都额外的多了一个双链表的机制记录它前后元素的位置。

2.4.2TreeSet集合

2.4.2.1TreeSet集合的特点和注意事项

特点:不重复、无索引、可排序(默认升序排序 ,按照元素的大小,由小到大排序)

底层是基于红黑树实现的排序。

注意:

对于数值类型:Integer , Double,默认按照数值本身的大小进行升序排序。

对于字符串类型:默认按照首字符的编号升序排序。

对于自定义类型如Student对象,TreeSet默认是无法直接排序的。

2.4.2.2TreeSet自定义排序规则

TreeSet集合存储自定义类型的对象时,必须指定排序规则,支持如下两种方式来指定比较规则。

方式一

让自定义的类(如学生类)实现Comparable接口,重写里面的compareTo方法来指定比较规则。

方式二

通过调用TreeSet集合有参数构造器,可以设置Comparator对象(比较器对象,用于指定比较规则。

public TreeSet(Comparator<? super E> comparator)

 根据方式一解决对象排序

 根据方式二解决对象排序 

注意:如果既用了方式一又用了方式二进行自定义排序,那么TreeSet就近选择自己自带的比较器对象进行排序; 

自定义排序总结:

两种方式中,关于返回值的规则:

  • 如果认为第一个元素 >  第二个元素 返回正整数即可。
  • 如果认为第一个元素 < 第二个元素返回负整数即可。
  • 如果认为第一个元素 = 第二个元素返回0即可,此时Treeset集合只会保留一个元素,认为两者重复。

2.5总结

1)、如果希望记住元素的添加顺序,需要存储重复的元素,又要频繁的根据索引查询数据

用ArrayList集合(有序、可重复、有索引),底层基于数组的。(常用) 

2)、如果希望记住元素的添加顺序,且增删首尾数据的情况较多

用LinkedList集合(有序、可重复、有索引),底层基于双链表实现的。

3).  如果不在意元素顺序,也没有重复元素需要存储只希望增删改查都快

用HashSet集合(无序,不重复,无索引),底层基于哈希表实现的。 (常用)

4).如果希望记住元素的添加顺序,也没有重复元素需要存储,且希望增删改查都快?

用LinkedHashSet集合(有序,不重复,无索引), 底层基于哈希表和双链表。

5).  如果要对元素进行排序,也没有重复元素需要存储?且希望增删改查都快?

用TreeSet集合,基于红黑树实现。

3.Collection其他相关知识

3.1可变参数

就是一种特殊形参,定义在方法、构造器的形参列表里,格式是:数据类型...参数名称;

可变参数的特点和好处

特点:可以不传数据给它;可以传一个或者同时传多个数据给它;也可以传一个数组给它。

好处:常常用来灵活的接收数据。

可变参数的注意事项:

  • 可变参数在方法内部就是一个数组。
  • 一个形参列表中可变参数只能有一个
  • 可变参数必须放在形参列表的最后面
package com.test.可删;
import java.util.Arrays;
public class Test {
    public static void main(String[] args) {
        // 特点:
        test(); // 不传数据
        test(10); // 传输一个数据给它
        test(10, 20, 30); // 传输多个数据给它
        test(new int[]{10, 20, 30, 40}); // 传输一个数组给可变参数
    }
    // 注意事项1:一个形参列表中,只能有一个可变参数。
    // 注意事项2:可变参数必须放在形参列表的最后面
    public static void test(int...nums){
        // 可变参数在方法内部,本质就是一个数组。
        System.out.println(nums.length);
        System.out.println(Arrays.toString(nums));
        System.out.println("-----------------------------------------");
    }
}

4.Collections工具类

Collections是一个用来操作集合的工具类

Collections提供的常用静态方法

package com.test.可删;
import com.test.集合框架.p140.Student;
import java.util.*;
public class Test {
    public static void main(String[] args) {
        // 1、public static <T> boolean addAll(Collection<? super T> c, T...elements):为集合批量添加数据
        List<String> names = new ArrayList<>();
        Collections.addAll(names, "张三", "王五", "李四", "张麻子");
        System.out.println(names);//[张三, 王五, 李四, 张麻子]
        // 2、public static void shuffle(List<?> list):打乱List集合中的元素顺序。
        Collections.shuffle(names);
        System.out.println(names);
        // 3、 public static <T> void sort(List<T> list):对List集合中的元素进行升序排序。
        List<Integer> list = new ArrayList<>();
        list.add(3);
        list.add(5);
        list.add(2);
        Collections.sort(list);
        System.out.println(list);//[2, 3, 5]
        // 4、public static <T> void sort(List<T> list, Comparator<? super T> c): 对List集合中元素,按照比较器对象指定的规则进行排序
        List<Student> students = new ArrayList<>();
        students.add(new Student("蜘蛛精",23, 169.7));
        students.add(new Student("紫霞",22, 169.8));
        students.add(new Student("紫霞",22, 169.8));
        students.add(new Student("至尊宝",26, 165.5));
        Collections.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return Double.compare(o1.getHeight(), o2.getHeight());
            }
        });
        System.out.println(students);
    }
}

 注意:Collections只能支持对List集合进行排序

5.Map集合

认识Map集合

  • Map集合称为双列集合,格式:{key1=value1 , key2=value2 , key3=value3 , ...}, 一次需要存一对数据做为一个元素.
  • Map集合的每个元素“key=value”称为一个键值对/键值对对象/一个Entry对象,Map集合也被叫做“键值对集合”
  • Map集合的所有键是不允许重复的,但值可以重复,键和值是一一对应的,每一个键只能找到自己对应的值

Map集合在什么业务场景下使用

需要存储一一对应的数据时,就可以考虑使用Map集合来做

package com.test.可删;
import java.util.*;
public class Test {
    public static void main(String[] args) {
        // Map<String, Integer> map = new HashMap<>(); // 一行经典代码。 按照键 无序,不重复,无索引。
        Map<String, Integer> map = new LinkedHashMap<>(); // 有序,不重复,无索引。
        map.put("手表", 100);
        map.put("手表", 220); // 后面重复的数据会覆盖前面的数据(键)
        map.put("手机", 2);
        map.put("Java", 2);
        map.put(null, null);
        System.out.println(map);//{手表=220, 手机=2, Java=2, null=null}
        Map<Integer, String> map1 = new TreeMap<>(); // 可排序,不重复,无索引
        map1.put(23, "Java");
        map1.put(23, "MySQL");
        map1.put(19, "李四");
        map1.put(20, "王五");
        System.out.println(map1);//{19=李四, 20=王五, 23=MySQL}
    }
}

5.1Map集合的常用方法

Map是双列集合的祖宗,它的功能是全部双列集合都可以继承过来使用的。

Map的常用方法如下:

package com.test.可删;
import java.util.*;
public class Test {
    public static void main(String[] args) {
        // 1.添加元素: 无序,不重复,无索引。
        Map<String, Integer> map = new HashMap<>();
        map.put("手表", 100);
        map.put("手表", 220);
        map.put("手机", 2);
        map.put("Java", 2);
        map.put(null, null);
        System.out.println(map);
        // map = {null=null, 手表=220, Java=2, 手机=2}

        // 2.public int size():获取集合的大小
        System.out.println(map.size());//4

        // 3、public void clear():清空集合
        //map.clear();
        //System.out.println(map);//{}

        // 4.public boolean isEmpty(): 判断集合是否为空,为空返回true ,反之!
        System.out.println(map.isEmpty());//false

        // 5.public V get(Object key):根据键获取对应值
        int v1 = map.get("手表");
        System.out.println(v1);//220
        System.out.println(map.get("手机")); // 2
        System.out.println(map.get("张三")); // null

        // 6. public V remove(Object key):根据键删除整个元素(删除键会返回键的值)
        System.out.println(map.remove("手表"));//220
        System.out.println(map);//{null=null, Java=2, 手机=2}

        // 7.public  boolean containsKey(Object key): 判断是否包含某个键 ,包含返回true ,反之
        System.out.println(map.containsKey("手表")); // false
        System.out.println(map.containsKey("手机")); // true
        System.out.println(map.containsKey("java")); // false
        System.out.println(map.containsKey("Java")); // true

        // 8.public boolean containsValue(Object value): 判断是否包含某个值。
        System.out.println(map.containsValue(2)); // true
        System.out.println(map.containsValue("2")); // false

        // 9.public Set<K> keySet(): 获取Map集合的全部键。
        Set<String> keys = map.keySet();
        System.out.println(keys);//[null, Java, 手机]

        // 10.public Collection<V> values(); 获取Map集合的全部值。
        Collection<Integer> values = map.values();
        System.out.println(values);//[null, 2, 2]

        // 11.把其他Map集合的数据倒入到自己集合中来。(拓展)
        Map<String, Integer> map1 = new HashMap<>();
        map1.put("java1",  10);
        map1.put("java2",  20);
        Map<String, Integer> map2 = new HashMap<>();
        map2.put("java3",  10);
        map2.put("java2",  222);
        map1.putAll(map2); // putAll:把map2集合中的元素全部倒入一份到map1集合中去。
        System.out.println(map1);//{java3=10, java2=222, java1=10}
        System.out.println(map2);//{java3=10, java2=222}
    }
}

 5.2Map集合的遍历方式

(1)Map集合的遍历方式一:键找值

先获取Map集合全部的键,再通过遍历键来找值

需要用到Map的如下方法:

package com.test.可删;
import java.util.*;
public class Test {
    public static void main(String[] args) {
        // 准备一个Map集合。
        Map<String, Double> map = new HashMap<>();
        map.put("蜘蛛精", 162.5);
        map.put("蜘蛛精", 169.8);
        map.put("紫霞", 165.8);
        map.put("至尊宝", 169.5);
        map.put("牛魔王", 183.6);
        System.out.println(map);
        // map = {蜘蛛精=169.8, 牛魔王=183.6, 至尊宝=169.5, 紫霞=165.8}
        // 1、获取Map集合的全部键
        Set<String> keys = map.keySet();
        // System.out.println(keys);
        // [蜘蛛精, 牛魔王, 至尊宝, 紫霞]
        //         key
        // 2、遍历全部的键,根据键获取其对应的值
        for (String key : keys) {
            // 根据键获取对应的值
            double value = map.get(key);
            System.out.println(key + "=====>" + value);
        }
    }
}

(2)Map集合的遍历方式二:键值对

把“键值对“看成一个整体进行遍历(难度较大)

package com.test.可删;
import java.util.*;
public class Test {
    public static void main(String[] args) {
        Map<String, Double> map = new HashMap<>();
        map.put("蜘蛛精", 169.8);
        map.put("紫霞", 165.8);
        map.put("至尊宝", 169.5);
        map.put("牛魔王", 183.6);
        System.out.println(map);
        // map = {蜘蛛精=169.8, 牛魔王=183.6, 至尊宝=169.5, 紫霞=165.8}
        // entries = [(蜘蛛精=169.8), (牛魔王=183.6), (至尊宝=169.5), (紫霞=165.8)]
        //                                                         entry
        // 1、调用Map集合提供entrySet方法,把Map集合转换成键值对类型的Set集合
        Set<Map.Entry<String, Double>> entries = map.entrySet();
        for (Map.Entry<String, Double> entry : entries) {
            String key = entry.getKey();
            double value = entry.getValue();
            System.out.println(key + "---->" + value);
        }
    }
}

(3)Map集合的遍历方式三:Lambda  

需要用到Map的如下方法

package com.test.可删;
import java.util.*;
public class Test {
    public static void main(String[] args) {
        Map<String, Double> map = new HashMap<>();
        map.put("蜘蛛精", 169.8);
        map.put("紫霞", 165.8);
        map.put("至尊宝", 169.5);
        map.put("牛魔王", 183.6);
        System.out.println(map);
        // map = {蜘蛛精=169.8, 牛魔王=183.6, 至尊宝=169.5, 紫霞=165.8}
//        map.forEach(new BiConsumer<String, Double>() {
//            @Override
//            public void accept(String k, Double v) {
//                System.out.println(k + "---->" + v);
//            }
//        });
        map.forEach(( k,  v) -> {
            System.out.println(k + "---->" + v);
        });
    }
}

 5.3HashMap集合的底层原理

HashMap(由键决定特点): 无序、不重复、无索引;  (用的最多)

HashMap跟HashSet的底层原理是一模一样的,都是基于哈希表实现的。

实际上:原来学的Set系列集合的底层就是基于Map实现的,只是Set集合中的元素只要键数据,不要值数据而已。

HashMap底层原理基于哈希表实现

  • HashMap集合是一种增删改查数据,性能都较好的集合
  • 但是它是无序,不能重复,没有索引支持的(由键决定特点)
  • HashMap的键依赖hashCode方法和equals方法保证键的唯一
  • 如果键存储的是自定义类型的对象,可以通过重写hashCode和equals方法,这样可以保证多个对象内容一样时,HashMap集合就能认为是重复的。

5.4LinkedHashMap集合的底层原理 

LinkedHashMap (由键决定特点): 有序、不重复、无索引。

 底层数据结构依然是基于哈希表实现的,只是每个键值对元素又额外的多了一个双链表的机制记录元素顺序(保证有序)

实际上:原来学习的LinkedHashSet集合的底层原理就是LinkedHashMap。

5.5TreeMap集合的底层原理 

TreeMap (由键决定特点):按照键的大小默认升序排序、不重复、无索引。

原理:TreeMap跟TreeSet集合的底层原理是一样的,都是基于红黑树实现的排序。

TreeMap集合同样也支持两种方式来指定排序规则

  • 让类实现Comparable接口,重写比较规则。
  • TreeMap集合有一个有参数构造器,支持创建Comparator比较器对象,以便用来指定比较规则。 

6.集合的嵌套

集合的嵌套:集合中的元素又是一个集合 

案例可参考链接:

java集合篇之练习题(List,Map等的应用练习)-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2260179.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ansible自动化运维(一)简介及清单,模块

相关文章ansible自动化运维&#xff08;二&#xff09;playbook模式详解-CSDN博客ansible自动化运维&#xff08;三&#xff09;jinja2模板&&roles角色管理-CSDN博客ansible自动化运维&#xff08;四&#xff09;运维实战-CSDN博客 ansible自动化运维工具 1.什么是自…

期末复习-编译原理

一、引论 1.编译、翻译、解释的概念&#xff08;掌握&#xff09; 翻译程序&#xff1a;将一种语言程序&#xff08;源&#xff09;转换成另一种语言程序&#xff08;目标&#xff09;&#xff0c;两者在逻辑上是等价的。 如果源语言是高级语言&#xff0c;目标语言是低级语言…

pytorch bilstm crf的教程,注意 这里不支持批处理,要支持批处理 用torchcrf这个。

### Bi-LSTM Conditional Random Field ### pytorch tutorials https://pytorch.org/tutorials/beginner/nlp/advanced_tutorial.html ### 模型主要结构&#xff1a; ![title](sources/bilstm.png) pytorch bilstm crf的教程&#xff0c;注意 这里不支持批处理 Python version…

docker安装、升级、以及sudo dockerd --debug查看启动失败的问题

1、docker安装包tar下载地址 Index of linux/static/stable/x86_64/ 2、下载tgz文件并解压 tar -zxvf docker-24.0.8.tgz 解压后docker文件夹下位docker相关文件 3、将老版本docker相关文件&#xff0c;备份 将 /usr/bin/docker下docker相关的文件&#xff0c;mv到备份目录…

hive—炸裂函数explode/posexplode

1、Explode炸裂函数 将hive某列一行中复杂的 array 或 map 结构拆分成多行&#xff08;只能输入array或map&#xff09; 语法&#xff1a; select explode(字段) as 字段命名 from 表名; 举例&#xff1a; 1&#xff09;explode(array)使得结果中将array列表里的每个元素生…

【Android学习】RxJava

文章目录 资料连接1. Merge & Zip操作符: 合并数据源2. Map & FlapMap & ConcatMap & Buffer: 变换操作符3. retry & retryUntil & retryWhen : 错误处理操作符4. Transformer & Compose 转换符 资料连接 Android RxJava&#xff1a; 这是一份全面…

浅谈Kubernetes(K8s)之RC控制器与RS控制器

1.RC控制器 1.1RC概述 Replication Controller 控制器会持续监控正在运行的Pod列表&#xff0c;并保证相应类型的Pod的数量与期望相符合&#xff0c;如果Pod数量过少&#xff0c;它会根据Pod模板创建新的副本&#xff0c;反之则会删除多余副本。通过RC可实现了应用服务的高可用…

直流开关电源技术及应用

文章目录 1. 开关电源概论1.1 开关电源稳压原理1.1.1 开关电源稳压原理核心组成部分及其作用工作过程稳压原理 1. 开关电源概论 1.1 开关电源稳压原理 为了提高效率&#xff0c;必须使功率调整器件处于开关工作状态。 作为开关而言&#xff0c;导通时压降很小&#xff0c;几乎…

解决 MyBatis 中空字符串与数字比较引发的条件判断错误

问题复现 假设你在 MyBatis 的 XML 配置中使用了如下代码&#xff1a; <if test"isCollect ! null"><choose><when test"isCollect 1">AND exists(select 1 from file_table imgfile2 where task.IMAGE_SEQimgfile2.IMAGE_SEQ and im…

如何windows命令行使用kali?ssh连接高效又快捷

一、打开虚拟机kali进入cmd中 输入vim /etc/ssh/sshd_config&#xff0c;&#xff08;注意这里需要使用root权限&#xff09; 二、进入编辑文件页面 找到PermitRootLogin prohibit-password和 PasswordAuthentication no两行 将“prohibit-password”修改为“yes”&#xff0…

自动化测试之单元测试框架

单元测试框架 一、单元测试的定义 1&#xff1a;什么是单元测试&#xff1f; 还记不记得我们软件测试学习的时候&#xff0c;按照定义&#xff1a;单元测试就是对单个模块或者是单个函数进行测试&#xff0c;一般是开发做的&#xff0c;按照阶段来分&#xff0c;一般就是单元…

ansible部署nginx:1个简单的playbook脚本

文章目录 hosts--ventoryroles执行命令 使用ansible向3台centos7服务器上安装nginx hosts–ventory [rootstand playhook1]# cat /root/HOSTS # /root/HOSTS [webservers] 192.168.196.111 ansible_ssh_passpassword 192.168.196.112 ansible_ssh_passpassword 192.168.196.1…

SpringBoot左脚进门之Maven管理家

一、概念 Maven 是一个项目管理和整合工具。通过对 目录结构和构建生命周期 的标准化&#xff0c; 使开发团队用极少的时间就能够自动完成工程的基础构建配置。 Maven 简化了工程的构建过程&#xff0c;并对其标准化&#xff0c;提高了重用性。 Maven 本地仓库 (Local Reposi…

最短路----Dijkstra算法详解

简介 迪杰斯特拉&#xff08;Dijkstra&#xff09;算法是一种用于在加权图中找到单个源点到所有其他顶点的最短路径的算法。它是由荷兰计算机科学家艾兹格迪科斯彻&#xff08;Edsger Dijkstra&#xff09;在1956年提出的。Dijkstra算法适用于处理带有非负权重的图。迪杰斯特拉…

论文概览 |《Urban Analytics and City Science》2022.11 Vol.49 Issue.9

本次给大家整理的是《Environment and Planning B: Urban Analytics and City Science》杂志2022年11月第49卷第9期的论文的题目和摘要&#xff0c;一共包括19篇SCI论文&#xff01; 论文1 On economic and urban growth 经济发展与城市增长 【摘要】 The dominant imperativ…

软件安装不成功,一直出现“chrome_elf.dll丢失”问题是什么原因?“chrome_elf.dll丢失”要怎么解决和预防?

软件安装遇阻&#xff1a;“chrome_elf.dll丢失”问题全解析与解决方案 在软件安装与运行的过程中&#xff0c;我们时常会遇到各式各样的错误提示&#xff0c;其中“chrome_elf.dll丢失”便是较为常见的一种。这个错误不仅阻碍了软件的正常安装&#xff0c;也给用户带来了不小…

04面向对象篇(D4_OOT(D1_OOT - 面向对象测试))

目录 一、 面向对象影响测试 1. 封装性影响测试 2. 继承性影响测试 3. 多态性影响测试 二、 面向对象测试模型 三、 面向对象分析测试 1. 对象测试 2. 结构测试 3. 主题测试 4. 属性和实例关联测试 5. 服务和消息关联测试 四、面向对象设计测试 1. 对认定类测试 …

java之静态变量和方法(类变量、类方法)

1 类变量 1.1 简要介绍 由一个简单的程序引出&#xff1a; public class Example1 {int n;static int num 10; //有 static 修饰//此时 num 即为一个类变量&#xff08;静态变量&#xff09;&#xff0c;static 表示静态的//这个变量的最大特点是&#xff0c;它会被 Exampl…

朗致面试---IOS/安卓/Java/架构师

朗致面试---IOS/安卓/Java/架构师 一、面试概况二、总结三、算法题目参考答案 一、面试概况 一共三轮面试&#xff1a; 第一轮是逻辑行测&#xff0c;25道题目&#xff0c;类似于公务员考试题目&#xff0c;要求90分钟内完成。第二轮是技术面试&#xff0c;主要是做一些数据结…

五、网络层:控制平面,《计算机网络(自顶向下方法 第7版,James F.Kurose,Keith W.Ross)》

目录 一、导论 二、路由选择算法 2.1 路由&#xff08;route&#xff09;的概念 2.2 网络的图抽象 2.2.1 边和路由的代价 2.2.2 最优化原则 2.3 路由的原则 2.4 路由选择算法的分类 2.5 link state 算法 2.5.1 LS路由工作过程 2.5.2 链路状态路由选择&#xff08;lin…