2-Java进阶知识总结-3-集合

news2024/9/21 23:35:59

文章目录

  • 补充知识-泛型
    • 版本信息
    • 泛型类
      • 常见泛型标识符
      • 泛型应用实例
      • 注意事项
    • 泛型方法
      • 非静态的泛型方法
      • 静态的泛型方法:必须声明出自己独立的泛型
    • 泛型接口
    • 泛型通配符
  • 补充知识-树
    • 基本概念
    • 二叉树-普通二叉树
    • 二叉树-二叉查找树
      • 添加节点流程
      • 优点、不足
    • 二叉树-平衡二叉树
      • 旋转机制
    • 二叉树-红黑树
      • 红黑规则
  • 补充知识-常见数据结构
    • 队列
    • 链表
    • 单项链表和双向链表
    • 集合底层数据结构
      • Collection-List集合
      • Collection-Set集合
      • Map集合
  • 集合
  • 集合分类
    • 大分类
    • 小分类
      • Collection接口的子类
      • Map接口的子类
  • 集合的遍历方式
    • 通用遍历方式
      • 迭代器
      • 增强for循环
      • forEach方法
    • 额外遍历方式-List集合
      • 普通for循环
      • ListIterator(List集合特有的迭代器)
  • Collection接口--通用函数
  • Collection接口--List接口-ArrayList
    • ArrayList长度可变原理
  • Collection接口--List接口-LinkedList
  • Collection接口--Set接口-TreeSet
    • 两种排序规则-自然排序
      • 常见类排序:String,默认增序排序
      • 自定义类排序
    • 两种排序规则-比较器排序
    • 两种排序规则优先级
  • Collection接口--Set接口-HashSet
    • 版本信息
    • 数据存储过程
    • 数组扩容
    • 链表转红黑树
    • 特点
  • Collection接口--Set接口-LinkedHashSet
  • Collection接口--总结
    • 类型选用
    • Collections工具类
  • Map接口
    • 基础介绍
    • Map类别
    • 通用方法
    • 底层原理-HashMap举例
    • 遍历方式
      • 通过forEach方法遍历
      • 通过键值对对象获取键和值
      • 通过键找值
    • Map集合选用

补充知识-泛型

版本信息

JDK5引入, 可以在编译阶段约束操作的数据类型, 并进行检查

  • 即统一数据类型,将运行时期的错误提升到编译期

泛型类

不知道使用者想要添加什么类型的数据,就给出一个泛型类

常见泛型标识符

ETKV
ElementTypeKeyValue
表示集合的元素类型表示任意类型表示关键字类型表示值类型

泛型应用实例

package com.itheima.day10.generics;

import java.util.ArrayList;

public class GenericsDemo2 {
    public static void main(String[] args) {
        Student<Integer> stu = new Student<>(); // 正确
        Student<int> stu = new Student<>();   // 错误,泛型类只能是引用数据类型
    }
}

class Student<E> {
    private E e;

    public E getE() {
        return e;
    }

    public void setE(E e) {
        this.e = e;
    }
}

注意事项

  • 当创建对象的时候,才能确定泛型类具体的类别

  • !!!泛型类只能写引用数据类型

泛型方法

非静态的泛型方法

  • 根据类的泛型去匹配

  • 上述 getE方法、setE方法

静态的泛型方法:必须声明出自己独立的泛型

  • 静态方法随着类的加载而加载,类还没创建,就没有具体类型,静态方法就有问题了。所以要声明自己独立的类型
  • 在调用方法,传入具体参数的时候,确定到静态方法具体的泛型类型
package com.itheima.day10.generics;

public class GenericsDemo3 {
    public static void main(String[] args) {

        String[] arr1 = {"张三", "李四", "王五"};
        Integer[] arr2 = {11, 22, 33};
        Double[] arr3 = {11.1, 22.2, 33.3};

        printArray(arr1);
        printArray(arr2);
        printArray(arr3);


    }

    // static后边的T
    public static <T> void printArray(T[] arr) {
        System.out.print("[");
        for (int i = 0; i < arr.length - 1; i++) {
            System.out.print(arr[i] + ", ");
        }
        System.out.println(arr[arr.length - 1] + "]");
    }
}

泛型接口

类实现接口的时候,接口带有泛型

  • 类实现接口的时候,直接确定类型
  • 延续接口的泛型,等创建对象的时候确定
package com.itheima.day10.generics;

import java.util.ArrayList;
import java.util.List;

public class GenericsDemo4 {
    public static void main(String[] args) {
        InterBImpl<String> i = new InterBImpl<>();
    }
}


interface Inter<E> {
    void show(E e);
}

// 类实现接口的时候,直接确定类型
class InterAImpl implements Inter<String> {

    @Override
    public void show(String s) {

    }
}

// 延续接口的泛型,等创建对象的时候确定
class InterBImpl<E> implements Inter<E>{

    @Override
    public void show(E e) {

    }
}

泛型通配符

想要一个方法可以传入不同的对象类型

?? extends E? super E
任意类型E及E的子类E及E的父类
package com.itheima.day10.generics;

import java.util.ArrayList;

public class GenericsDemo5 {
    /*
        泛型通配符

                ? : 任意类型

                ? extends E : 可以传入的是E, 或者是E的子类

                ? super E : 可以传入的是E, 或者是E的父类
     */
    public static void main(String[] args) {

        ArrayList<Coder> list1 = new ArrayList<>();
        list1.add(new Coder());

        ArrayList<Manager> list2 = new ArrayList<>();
        list2.add(new Manager());

        method(list1);
        method(list2);

    }

    public static void method(ArrayList<? extends Employee> list){
        for (Employee o : list) {
            o.work();
        }
    }
    
    public static void method1(ArrayList<? super Employee> list){
        for (Object A : list) {
            Employee o = (Employee)A;
            o.work();
        }
    }    
}

abstract class Employee {
    private String name;
    private double salary;

    public Employee() {
    }

    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

    public abstract void work();

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public String toString() {
        return "Employee{name = " + name + ", salary = " + salary + "}";
    }
}

class Coder extends Employee {
    @Override
    public void work() {
        System.out.println("程序员写代码...");
    }
}

class Manager extends Employee {
    @Override
    public void work() {
        System.out.println("项目经理分配任务...");
    }
}

补充知识-树

基本概念

image-20231017154352376

概念理解
节点(其他叫法:结点、Node)上边的每一个圈圈都是一个节点;
(节点内部存储:父节点地址、节点值、左子节点地址、右子节点地址)
每一个节点的子节点数量
(二叉数中,任意节点的度<=2)
树高整棵树的层数
(上边数的树高=4)
根节点最顶层的节点(22)
左子节点22的左子节点是18
右子节点22的右子节点是26
根节点的左子树18节点及其所有子节点
根节点的右子树26节点及其所有子节点

二叉树-普通二叉树

无排序

image-20231017155918842

二叉树-二叉查找树

有排序

又名:二叉排序树、二叉搜索树

image-20231017155958621

  • 每个节点最多两个子节点

  • 任意节点左子树上的值都小于当前节点

  • 任意节点右子树的值都大于当前节点

添加节点流程

  • 小的节点存左边

  • 大的节点存右边

  • 一样的节点不存

优点、不足

  • 优点:元素查找速度快,每一次查找,筛选掉剩余元素的一半

  • 不足:特殊二叉查找树(所有节点仅有右节点或左节点),每次查找并不能过滤掉一半元素,查找速度跟数组一样

二叉树-平衡二叉树

任意节点左右子树高度差不超过1

旋转机制

  • 挺巧妙地,用到了再说

二叉树-红黑树

  • 不是通过高度来平衡的,而是通过红黑规则来平衡的

红黑规则

  • 用到再说

补充知识-常见数据结构

数据结构结构操作特点补充
一端开口(栈顶)、一端封闭(栈底)进栈/压栈、出栈/弹栈后进先出,先进后出
队列一端开口(后端)、一端开口(前端)入队列(后端)、出队列(前端)先进先出,后进后出
数组地址值、索引根据地址值和索引定位数据查询速度快(且一致):索引+地址值定位;
增、删效率低:增删过程大概率伴随大量数据移动
链表见下图查询慢:查询任何数据都要从头开始查
增删相对快:查到对应元素,更改节点存储内容
存储内存不连续
双向链表见下图同【链表】存储内存不连续
见【补充知识-树】

image-20231018152435202

队列

image-20231018152516475

链表

image-20231017092555108

单项链表和双向链表

image-20231017092826875

集合底层数据结构

Collection-List集合

ArrayListLinkedList
数组双向链表

Collection-Set集合

Set的底层就是Map

TreeSetHashSetLinkedHashSet
红黑树哈希表(数组+链表+红黑树)哈希表+双向链表

Map集合

TreeMapHashMapLinkedHashMap
红黑树哈希表(数组+链表+红黑树)哈希表+双向链表

集合

是一种容器,用来装数据,类似数组,但长度可变

集合分类

大分类

单列集合双列集合
区别一次添加一个元素一次添加两个元素
成员ArrayList、LinkedList、TreeSet、HashSet、LinkedHashSetTreeMap、HashMap、LinkedHashMap
接口实现实现Collection接口实现Map接口

小分类

Collection接口的子类

List接口Set接口
成员ArrayList、LinkedListTreeSet、HashSet、LinkedHashSet
特点存取有序、有索引、可以重复存储存取无序、没有索引、不可以重复存储
  • TreeSet可以实现排序,按照排序规则输出元素
  • HashSet保证元素唯一
  • LinkedHashSet可以保证存储顺序

Map接口的子类

Map接口
成员TreeMap、HashMap、LinkedHashMap
特点同Set接口

集合的遍历方式

通用遍历方式

迭代器

增强for循环

forEach方法

package com.itheima.collection;

import com.itheima.domain.Student;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class CollectionTest2 {
    public static void main(String[] args) {
        Collection<Student> c = new ArrayList<>();

        c.add(new Student("张三", 23));
        c.add(new Student("李四", 24));
        c.add(new Student("王五", 25));


        // 1. 获取迭代器
        Iterator<Student> it = c.iterator();

        // 2. 循环判断, 集合中是否还有元素
        while (it.hasNext()) {
            // 3. 调用next方法, 将元素取出
            Student stu = it.next();
            System.out.println(stu.getName() + "---" + stu.getAge());
        }

        System.out.println("--------------------");

        // 使用增强for循环遍历集合:内部还是迭代器,通过.class文件可以看出来
        for (Student stu : c) {
            System.out.println(stu);
        }

        System.out.println("--------------------");

        // foreach方法遍历集合:匿名内部类
        c.forEach(stu -> System.out.println(stu));

    }
}

额外遍历方式-List集合

普通for循环

ListIterator(List集合特有的迭代器)

package com.itheima.collection.list;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class ListDemo2 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("abc");
        list.add("bbb");
        list.add("ccc");
        list.add("abc");

        // 普通for循环
        for (int i = 0; i < list.size(); i++) {
            String s = list.get(i);
            System.out.println(s);
        }

        System.out.println("---------------");

        // 迭代器
        // 先调用hasPrevious会打印不出来数据
        /// 需要先调用hasNext,再掉用hasPrevious,才能保证一次正向打印,一次反向打印
        ListIterator<String> it = list.listIterator();

        while(it.hasPrevious()){
            String s = it.previous();
            System.out.println(s);
        }

        System.out.println("---------------");

        while (it.hasNext()) {
            String s = it.next();
            System.out.println(s);
        }
    }
}

ListIterator(List集合特有的迭代器)遍历过程中的添加、删除元素注意事项

用迭代器遍历过程中,调用【集合对象】的添加、删除操作,就会出现异常

用【迭代器】对象的添加或删除方法,即可避免异常

  • 普通迭代器:Iterator,仅支持删除操作,不支持添加操作
  • List迭代器:ListIterator,既支持删除操作,也支持添加操作
package com.itheima.collection.list;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class ListDemo3 {
    public static void main(String[] args) {

        List<String> list = new ArrayList<>();

        list.add("眼瞅着你不是真正的高兴");
        list.add("温油");
        list.add("离开俺们这旮表面");
        list.add("伤心的人别扭秧歌");
        list.add("私奔到东北");

        ListIterator<String> it = list.listIterator();
        while (it.hasNext()) {
            String s = it.next();
            if ("温油".equals(s)) {
                it.add("哈哈");  // 没问题
                list.add("哈哈"); // 报错
                list.remove("温油"); // 报错
            }
        }
        System.out.println(list);
    }
}

Collection接口–通用函数

image-20231016192710344

  • remove()、contains()两个函数依赖对象底层的equals()方法

  • 若对象没有重写equals()方法,比较的是地址值,无法按照要求删除

  • 上述方法均以对象为参数,不以索引为参数(因为Collection接口里面的Set接口没有索引)

Collection接口–List接口-ArrayList

支持索引

增、删、改、查(索引)

package com.itheima.collection.list;

import java.util.ArrayList;
import java.util.List;

public class ListDemo1 {
    /*
        List接口的特点 : 存取有序, 有索引, 可以存储重复的

        和“索引”有关的API :
            public void add(int index, E element) : 在指定的索引位置, 添加元素
            public E remove(int index) : 根据索引删除集合中的元素
            public E set(int index, E element) : 根据索引修改集合中的元素
            public E get(int index) : 返回指定索引处的元素
     */
    public static void main(String[] args) {

        List<String> list = new ArrayList<>();

        list.add("张三");
        list.add("李四");
        list.add("王五");

        list.set(0, "赵六");
        list.remove(1);

        System.out.println(list.get(0));

        System.out.println(list);

        System.out.println("-------------------------");

        List<Integer> list2 = new ArrayList<>();

        list2.add(111);        // Integer e = 111;
        list2.add(222);
        list2.add(333);

        list2.remove(Integer.valueOf(222));

        System.out.println(list2);
    }
}
  • 根据索引删除元素是List接口(子)的特点

  • 根据元素删除元素是Collection接口(父)的特点

ArrayList长度可变原理

  • 空参构造时,底层创建长度为0的数组(非空参构造,创建长度为10的数组)
  • 添加第一个元素时,底层会创建一个新的长度为10的数组
  • 当数组存满时,会扩容1.5倍

Collection接口–List接口-LinkedList

支持索引

增、删、改、查、查首个、查尾部(非索引)

package com.itheima.collection.list;

import java.util.LinkedList;

public class LinkedListDemo {
    /*
        LinkedList 特有方法 :

            public void addFirst(E e) : 头部添加
            public void addLast(E e) : 尾部添加
            public E getFirst() : 获取第一个
            public E getLast() : 获取最后一个
            public E removeFirst() : 删除第一个
            public E removeLast() : 删除最后一个
     */
    public static void main(String[] args) {

        LinkedList<String> list = new LinkedList<>();

        list.add("张三");
        list.add("李四");
        list.add("王五");

        String s = list.get(1);
        System.out.println(s);

    }

    private static void method2() {
        LinkedList<String> list = new LinkedList<>();

        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("赵六");

        System.out.println(list.getFirst());
        System.out.println(list.getLast());

        list.removeFirst();
        list.removeLast();

        System.out.println(list);
    }

    private static void method1() {
        LinkedList<String> list = new LinkedList<>();

        list.addFirst("张三");
        list.addFirst("李四");
        list.addFirst("王五");
        list.addLast("赵六");

        // 王五 李四 张三 赵六

        System.out.println(list);
    }
}

LinkedList也归属与List接口,具有get(int index)方法,但是其底层是双向链表,get方法怎么实现?

  • 将索引和集合长度比较
  • 靠近头部:从头找数据,一个一个找
  • 靠近尾部:从尾找数据,一个一个找

不同于ArrayList的查询(地址值+索引)。LinkedList的存储内存不连续,是一个一个元素查找,速度慢

Collection接口–Set接口-TreeSet

对集合中的元素进行排序操作(底层红黑树实现)

两种排序规则-自然排序

常见类排序:String,默认增序排序

package com.itheima.day10.set;

import java.util.TreeSet;

public class TreeSetDemo1 {
    public static void main(String[] args) {
        TreeSet<String> ts = new TreeSet<>();
        ts.add("a");
        ts.add("d");
        ts.add("e");
        ts.add("c");
        ts.add("b");
        ts.add("b");
        ts.add("b");
        ts.add("b");
        ts.add("b");

        System.out.println(ts);  // [a, b, c, d, e]
    }
}

自定义类排序

  • 类实现Comparable接口

  • 重写compareTo方法

  • 根据返回值,组织排序规则

    • 返回负数:往树左边走

    • 返回正数:往树右边走

    • 返回0:不存(对于根节点除外,即第一个元素除外)

package com.itheima.day10.set;

import com.itheima.day10.domain.Student;

import java.util.TreeSet;

public class TreeSetDemo2 {
    public static void main(String[] args) {
        TreeSet<Student> ts = new TreeSet<>();

        ts.add(new Student("A", 23));
        ts.add(new Student("B", 26));
        ts.add(new Student("C", 27));
        ts.add(new Student("D", 20));

        // [Student{name = C, age = 27}, Student{name = B, age = 26}, Student{name = A, age = 23}, Student{name = D, age = 20}]
        System.out.println(ts);
    }
}

比较过程:

23+A—23+A
26+B—23+A
27+C—23+A
27+C—26+B
20+D—26+B
20+D—23+A

// Student类
package com.itheima.day10.domain;

public class Student implements Comparable<Student>{

    // this.xxx - o.xxx  正序
    // o.xxx - this.xxx  降序
    @Override
    public int compareTo(Student o) {
        System.out.println(this.getAge() + "+" + this.name + "---" + o.age + "+" + o.name);
        // 根据年龄做主要排序条件
        int ageResult = o.age - this.age;
        // 根据姓名做次要排序条件
        int nameResult = ageResult == 0 ? o.name.compareTo(this.name) : ageResult;
        // 判断姓名是否相同
        int result = nameResult == 0 ? 1 : nameResult;
        return result;
    }

    private String name;
    private int age;


    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "Student{name = " + name + ", age = " + age + "}";
    }
}

两种排序规则-比较器排序

  • 在 TreeSet 的构造方法中, 传入 Compartor 接口的实现类对象

  • 重写 compare 方法

  • 根据方法的返回值, 来组织排序规则

    • 负数 : 左边走

    • 正数 : 右边走

    • 0 : 不存

该接口也是函数式接口,可以写为Lambda表达式

package com.itheima.day10.set;

import com.itheima.day10.domain.Student;

import java.util.Comparator;
import java.util.TreeSet;

public class TreeSetDemo3 {  
    public static void main(String[] args) {
        TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                int ageResult = o1.getAge() - o2.getAge();
                return ageResult == 0 ? o1.getName().compareTo(o2.getName()) : ageResult;
            }
        });

        ts.add(new Student("赵六", 26));
        ts.add(new Student("李四", 24));
        ts.add(new Student("张三", 23));
        ts.add(new Student("王五", 25));
		
        // [Student{name = 张三, age = 23}, Student{name = 李四, age = 24}, Student{name = 王五, age = 25}, Student{name = 赵六, age = 26}]
        System.out.println(ts);
    }
}

两种排序规则优先级

如果同时具备比较器和自然排序, 会优先按照比较器的规则, 进行排序操作

  • 有些类给出默认的排序规则,不好重写其底层代码,就用比较器

Collection接口–Set接口-HashSet

可以保证数据唯一性

版本信息

JDK7JDK8
数组+链表数组+链表+红黑树

数据存储过程

  • 每个数据的存储都需要进行比较,根据比较结果来判断是否存
  • 需要重写存入对象的hashCode方法、equals方法
  • 创建一个默认长度16的数组,数组名table
  • 根据元素的哈希值跟数组的长度求余计算出应存入的位置(调用hashCode方法)
  • 判断当前位置是否为null,如果是null直接存入
  • 如果位置不为null,表示有元素,则调用equals方法比较
  • 如果一样,则不存,如果不一样,则存入数组
    • JDK 7新元素占老元素位置,指向老元素 (头插法)
    • JDK 8中新元素挂在老元素下面(尾插法)

image-20231018161129472

数组扩容

  • 条件1:数组存满到16*0.75(加载因子)=12时,就自动扩容,每次扩容为原先的两倍
  • 条件2:链表挂载元素超过了8个 (阈值) ,但数组长度没有到达64

链表转红黑树

  • 条件:链表挂载元素超过了8个 (阈值),且数组长度到达64

特点

  • 底层是哈希表存储数据,对增删改查数据性能都比较好

  • 存储的数据具有唯一性

  • 不对数据进行排序

Collection接口–Set接口-LinkedHashSet

image-20231018161913045

Collection接口–总结

类型选用

CaseChoice
如果想要集合中的元素可重复ArrayList
如果想要集合中的元素可重复,而且当前的增删操作明显多于查询LinkedList
如果想对集合中的元素去重HashSet
如果想对集合中的元素去重,而且保证存取顺序LinkedHashSet
如果想对集合中的元素进行排序TreeSet

Collections工具类

image-20231018162535633

package com.itheima.day11.tools;

import com.itheima.day11.domain.Student;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class CollectionsDemo {
    public static void main(String[] args) {
        // 批量添加
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "a", "b", "c", "d");
        System.out.println(list);

        // 二分查找 (前提: 必须是排好序的数据)
        System.out.println(Collections.binarySearch(list, "b"));

        // 洗牌
        Collections.shuffle(list);
        System.out.println(list);

        ArrayList<Student> nums = new ArrayList<>();
        Collections.addAll(nums, new Student("张三", 23), new Student("王五", 25), new Student("李四", 24));

        // 从集合中找最值
        System.out.println(Collections.max(nums));
        System.out.println(Collections.min(nums));

        // 对集合中的元素进行交换
        Collections.swap(nums, 0, 2);
        System.out.println(nums);

        // sort : 对集合进行排序
        ArrayList<Integer> box = new ArrayList<>();
        Collections.addAll(box, 1, 3, 5, 2, 4);
        Collections.sort(box, (o1, o2) -> o2 - o1);
        System.out.println(box);
    }
}

Map接口

基础介绍

  • Map是双列集合,每个元素包含两个数据
  • Map元素格式:key=value
    • key:不允许重复
    • value:允许重复
    • key-value一一对应
  • key-value整体,称为【键值对】或【键值对对象】,用Entry表示

Map类别

TreeMap、HashMap、LinkedHashMap

通用方法

Map是双列集合的顶层接口

image-20231018163606409

底层原理-HashMap举例

image-20231018163842215

  • 用键值对中的键来计算哈希值,与值无关
  • 后续原理同HashSet

遍历方式

通过forEach方法遍历

通过键值对对象获取键和值

通过键找值

package com.itheima.day11.map;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;

public class MapDemo3 {
    public static void main(String[] args) {
        HashMap<String, String> hm = new HashMap<>();
        hm.put("张三", "北京");
        hm.put("李四", "上海");
        hm.put("王五", "成都");

        hm.forEach((key, value) -> System.out.println(key + "---" + value));
    }

    private static void method2(HashMap<String, String> hm) {
        // 1. 获取到所有的键值对对象
        Set<Map.Entry<String, String>> entrySet = hm.entrySet();
        // 2. 遍历set集合获取每一个键值对对象
        for (Map.Entry<String, String> entry : entrySet) {
            // 3. 通过键值对对象, 获取键和值
            System.out.println(entry.getKey() + "---" + entry.getValue());
        }
    }

    private static void method1(HashMap<String, String> hm) {
        // 1. 获取到所有的键
        Set<String> keySet = hm.keySet();
        // 2. 遍历set集合, 获取每一个键
        for (String key : keySet) {
            // 3. 调用map集合的get方法, 根据键查找对应的值
            String value = hm.get(key);
            System.out.println(key + "---" + value);
        }
    }
}

Map集合选用

CaseChoice
如果想根据集合中的键进行去重HashMap
如果想根据键对集合中的元素去重,而且保证存取顺序LinkedHashMap
如果想根据集合中的键进行排序TreeMap

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

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

相关文章

了解松散类型

目录 松散类型带来的优势 灵活性和便利性 快速原型开发 动态类型 松散类型的注意事项 类型转换 隐式类型转换 如何正确使用松散类型&#xff1f; 动态类型 便捷的类型转换 灵活性与易用性 潜在的隐式类型转换 避免混淆和错误 当谈到JavaScript编程语言时&#xff…

app拉新平台推广渠道,地推网推接单神器

地推或网推不知道在哪里接单&#xff1f;信息差太大导致价格参差不齐&#xff0c;聚量推客人人高价置顶 聚量推客自己本身是服务商直营平台 相对来说数据更好&#xff0c;我们也拿到了平台首码&#xff1a;000000 填这个就行&#xff0c;属于官方渠道 平台最新上架的产品有&a…

Java即时通讯源码 IM即时通讯系统源码

Java即时通讯源码 IM即时通讯系统源码 基本功能说明及介绍&#xff1a; 客户端&#xff1a;安卓&#xff0c;苹果&#xff0c;&#xff08;可赠送web&#xff0c;pc&#xff09; 开发语言&#xff1a; Java OC C# 运行软件&#xff1a;eclipse Java xcode 数据库&#xff…

选择工业交换机时,需要关注哪些方面的性能?

在工业自动化、能源、交通等领域的网络通信中&#xff0c;工业交换机是一种非常重要的网络设备。它的性能和可靠性直接影响到整个网络的稳定性和安全性。因此&#xff0c;在选择工业交换机时&#xff0c;我们需要关注以下几个方面的性能&#xff1a; 1. 抗干扰性能&#xff1a;…

linux下安装 Chrome 和 chromedriver 以及 selenium webdriver 使用

1 安装 Chrome yum install https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm2 下载 chromedriver # 进入下载目录 cd soft/crawler_tools# 查看chrome 版本号 google-chrome --version# 在chromedriver下载地址中找到对应版本&#xff0c;下载对…

音频类型识别方案-audioset_tagging

audioset_tagging github上开源的音频识别模型&#xff0c;可以识别音频文件的类型并打分给出标签占比&#xff0c;如图 echo off set CHECKPOINT_PATH"module/Cnn14_mAP0.431.pth" set MODEL_TYPE"Cnn14" set CUDA_VISIBLE_DEVICES0 python pytorch\in…

谈谈多用户商城系统的优缺点

多用户商城系统是一种基于互联网的电子商务平台&#xff0c;可以给多个商家提供在线销售、交易和管理的功能。这种系统的出现&#xff0c;为商家和消费者之间的交流和交易提供了更加便捷和高效的方式。那么&#xff0c;多用户商城系统的优缺点有哪些呢&#xff1f; 一、多用户商…

实在智能受邀参加第14届珠中江数字化应用大会,AI赋能智能制造,共话“湾区经验”

制造业是实体经济的主体&#xff0c;是技术创新的主战场&#xff0c;是供给侧结构性改革的重要领域。抢占新一轮产业竞争制高点&#xff0c;制造业的数字化转型已成为行业升级的必由之路。 10月21日&#xff0c;第14届“珠中江”&#xff08;珠海、中山、江门&#xff09;数字…

Amazon商品详情API接口(标题|主图|SKU|价格|库存)

亚马逊商品详情API接口是亚马逊平台提供的API接口&#xff0c;可以通过程序调用API来获取亚马逊商品的相关数据&#xff0c;包括商品价格、库存、评价等信息。这些信息可以帮助开发者和商家更好地了解商品详情&#xff0c;优化用户体验&#xff0c;支持购买决策&#xff0c;竞品…

软件兼容性测试对软件产品起到什么作用?CMA、CNAS软件测评中心分享

软件兼容性测试是指检查软件之间能否正确地进行交互和共享信息。随着用户对来自各种类型软件之间共享数据能力和充分利用空间同时执行多个程序能力的要求&#xff0c;测试软件之间能否协作变得越来越重要。软件兼容性测试工作的目标是保证软件按照用户期望的方式进行交互。 1、…

哪些车企AEB标配率「不及格」

对于汽车智能化来说&#xff0c;基础安全不分高低配。但实际情况&#xff0c;却是另一番景象。 在全球范围&#xff0c;目前不少国家及地区的监管机构正在考虑将AEB&#xff08;紧急制动系统&#xff09;作为乘用车的标配纳入法规&#xff0c;“这是道路安全向前迈出了重要的一…

21.2 Python 使用Scapy实现端口探测

Scapy 是一款使用纯Python编写的跨平台网络数据包操控工具&#xff0c;它能够处理和嗅探各种网络数据包。能够很容易的创建&#xff0c;发送&#xff0c;捕获&#xff0c;分析和操作网络数据包&#xff0c;包括TCP&#xff0c;UDP&#xff0c;ICMP等协议&#xff0c;此外它还提…

【QT开发(15)】QT在没有桌面的系统中可以使用

在没有桌面的系统中&#xff0c;可以使用QT库。QT库可以在没有图形用户界面&#xff08;GUI&#xff09;的环境中运行&#xff0c;例如在服务器或命令行终端中。 这样就可利用Qt的&#xff1a; 对象模型&#xff0c;信号和槽容器类多线程和多进程网络编程 等

在Linux上实现ECAT主站

在Linux上实现ECAT主站 引言介绍EtherCATSOEM 使用下载ECAT主站编译 引言 EtherCAT由一个主站设备和多个从站设备组成。主站设备使用标准的以太网控制器&#xff0c;具有良好的兼容性&#xff0c;任何具有网络接口卡的计算机和具有以太网控制的嵌入式设备都可以作为EtherCAT的…

使用canvas实现时间轴上滑块的各种常用操作(仅供参考)

一、简介 使用canvas&#xff0c;模拟绘制时间轴区域&#xff0c;有时间刻度标尺&#xff0c;时间轴区域上会有多行&#xff0c;每行都有一个滑块。 1、时间刻度标尺可以拖动&#xff0c;会自动对齐整数点秒数&#xff0c;最小步数为0.1秒。 2、滑块可以自由拖动&#xff0c…

如何将Linux上部署的5.7MySql数据库编码修改utf8(最新版)

如何将Linux&#xff08;服务器&#xff09;上部署的5.7MySql数据库编码修改utf8&#xff08;最新版&#xff09; 一、解决办法步骤1步骤2&#xff08;此处为问题描述吐槽&#xff0c;可以直接跳过该步骤到步骤三&#xff09;步骤3步骤4步骤5 二、结果 # 前言 提示&#xff1a…

【java学习—九】类的成员之四:初始化块(1)

文章目录 1. 初始化块(代码块)的作用2. 静态代码块3. 非静态代码块和静态代码块的特点 1. 初始化块(代码块)的作用 作用&#xff1a;对java对象进行初始化      程序执行的顺序&#xff1a;     ①声明成员变量的默认值 --> ②显式初始化、多个初始化块依次被执行&a…

On Moving Object Segmentation from Monocular Video with Transformers 论文阅读

论文信息 标题&#xff1a;On Moving Object Segmentation from Monocular Video with Transformers 作者&#xff1a; 来源&#xff1a;ICCV 时间&#xff1a;2023 代码地址&#xff1a;暂无 Abstract 通过单个移动摄像机进行移动对象检测和分割是一项具有挑战性的任务&am…

智慧停车视频解决方案:如何让AI助力停车管理升级?

一、项目背景 停车场的管理区域由于面积比较大&#xff0c;进出车辆多&#xff0c;所以在保安方面决不能有任何的麻痹和松懈&#xff0c;继续采用过去保安方式已远远不能满足现代安全防范的需求。为满足停车场的安全和科学系统化管理的需要&#xff0c;以及为了对随时发生的情…