Java 进阶集合Set、Map(二)

一、Set集合

1、HashSet集合

1)原理

底层采用哈希表存储数据

2)组成

jdk8之前:底层数组+链表组成
jdk8之后:底层数组+链表+红黑树组成

3)哈希值

对象的内存地址经过处理后的结构,由于每个对象的内存地址都不一样,所以哈希码也不一样。更重要的是:这里的内存地址是JVM虚拟机虚拟出来的地址,并不是真实的物理内存地址

4)哈希值特点

同一个对象多次调用hashCode()方法返回的哈希值是相同的
默认情况下,不同对象的哈希值是不同的

5)jdk8哈希表流程:

Constructs a new, empty set; the backing HashMap instance has default initial capacity (16) and load factor (0.75).

创建一个新的空集合,默认初始值是16,加载因子(0.75)
根据元素的哈希值和数组的长度计算出应存入的位置
首先判断当前位置是否为NULL,空则直接存入,非空则equals方法比较属性值,相同则不存,不同则存入数组
当数组存储满足16*0.75=12时自动扩容,每次扩容会是当前容量的2倍
在这里插入图片描述

import java.util.HashSet;

public class ClassStructure {
    
    
    public static void main(String[] args) {
    
    
        HashSet<String> set = new HashSet<>();
        set.add("aa");
        set.add("bb");
        set.add("cc");
        set.add("aa");
        set.add("ee");
        set.add("ff1");
        set.add("ff2");
        set.add("ff3");
        System.out.println(set);
        //哈希值
        System.out.println(set.hashCode());
    }
}

2、LinkedHashSet集合

1)概述

有序、不重复、无索引
有序指保证存储和取出元素顺序一致

2)原理

底层数据结构哈希表,每个元素增加双链表机制记录数据存储顺序
在这里插入图片描述
在这里插入图片描述

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

public class ClassStructure {
    
    
    public static void main(String[] args) {
    
    
        Set set = new LinkedHashSet<>();
        set.add("aa");
        set.add(123);
        set.add(456);
        set.add("hello");
        System.out.println(set);
    }
}


3、TreeSet集合

不重复、无索引、可排序
可排序:按照元素的大小默认升序(有小到大)排序。
TreeSet集合底层是基于红黑树的数据结构实现排序的,增删改查性能都较好。

注意:TreeSet集合是一定要排序的,可以将元素按照指定的规则进行排序

1)默认规则

对于数值类型:Integer , Double,默认升序排序。
对于字符串类型:默认按照首字符的编号升序排序。
对于自定义类型对象,TreeSet无法直接排序。

2) 自定义规则

TreeSet集合有参数构造器,可以设置Comparator接口对应的比较器对象,来定制比较规则。
在这里插入图片描述

public class Student {
    
    
    private int id;
    private String name;
    private int age;
    public int getId() {
    
    
        return id;
    }
    public void setId(int id) {
    
    
        this.id = id;
    }
    public String getName() {
    
    
        return name;
    }
    public void setName(String name) {
    
    
        this.name = name;
    }
    public int getAge() {
    
    
        return age;
    }
    public void setAge(int age) {
    
    
        this.age = age;
    }
    @Override
    public String toString() {
    
    
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

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

public class ClassStructure {
    
    
    public static void main(String[] args) {
    
    
        Student stu = new Student();
        stu.setId(1);
        stu.setName("zhangsan");
        stu.setAge(11);
        Student stu1 = new Student();
        stu1.setId(3);
        stu1.setName("zhangsan3");
        stu1.setAge(33);
        Student stu2 = new Student();
        stu2.setId(2);
        stu2.setName("zhangsan2");
        stu2.setAge(22);
        Student stu3 = new Student();
        stu3.setId(5);
        stu3.setName("zhangsan5");
        stu3.setAge(55);
        Set<Student> set = new TreeSet<>(
                new Comparator<Student>() {
    
    
                    @Override
                    public int compare(Student o1, Student o2) {
    
    
                        return o1.getId()-o2.getId();
                    }
                }
        );
        set.add(stu);
        set.add(stu1);
        set.add(stu2);
        set.add(stu3);
        for (Student id:set){
    
    
            System.out.println(id);
        }
    }
}


让自定义的类,实现Comparable接口重写里面的compareTo方法来定制比较规则。

在这里插入图片描述

public class Student implements Comparable<Student>{
    
    
    private int id;
    private String name;
    private int age;
    public int getId() {
    
    
        return id;
    }
    public void setId(int id) {
    
    
        this.id = id;
    }
    public String getName() {
    
    
        return name;
    }
    public void setName(String name) {
    
    
        this.name = name;
    }
    public int getAge() {
    
    
        return age;
    }
    public void setAge(int age) {
    
    
        this.age = age;
    }
    @Override
    public String toString() {
    
    
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    /*
    默认升序
     */
    @Override
    public int compareTo(Student o) {
    
    
        return this.id - o.id;
    }
}

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

public class ClassStructure {
    
    
    public static void main(String[] args) {
    
    
        Student stu = new Student();
        stu.setId(1);
        stu.setName("zhangsan");
        stu.setAge(11);
        Student stu1 = new Student();
        stu1.setId(3);
        stu1.setName("zhangsan3");
        stu1.setAge(33);
        Student stu2 = new Student();
        stu2.setId(2);
        stu2.setName("zhangsan2");
        stu2.setAge(22);
        Student stu3 = new Student();
        stu3.setId(5);
        stu3.setName("zhangsan5");
        stu3.setAge(55);
        Set<Student> set = new TreeSet<>();
        set.add(stu);
        set.add(stu1);
        set.add(stu2);
        set.add(stu3);
        for (Student id:set){
    
    
            System.out.println(id);
        }
    }
}


4、可变参数(动参)

  • 定义

可变参数用在形参中可以接收多个数据。
可变参数的格式:数据类型…参数名称

  • 作用

接收参数非常灵活,方便。可以不接收参数,可以接收1个或者多个参数,也可以接收一个数组
可变参数在方法内部本质上就是一个数组。

  • 注意

一个形参列表中可变参数只能有一个
可变参数必须放在形参列表的最后面

  • 题目(实战),需求:

假如需要定义一个方法求和,该方法可以灵活的完成如下需求:
计算1个数据的和。
计算2个数据的和。
计算3个数据的和。
计算n个数据的和,甚至可以支持不接收参数进行调用。

在这里插入图片描述

public class ClassStructure {
    
    

    public static void Test(Integer... args) {
    
    
        int sum = 0;
        for (int ag : args) {
    
    
            sum += ag;
        }
        System.out.println(sum);
    }

    public static void main(String[] args) {
    
    
        Test(1);
        Test(1, 2);
        Test(1, 2, 3);
    }
}


二、Map集合

1、概述

Map是双列集合,每个元素包含两个数据,格式(Key=Value),也称为键值对集合

2、特点

Map集合的键是无序,不重复的,无索引的,值不做要求(可以重复)
Map集合后面重复的键对应的值会覆盖前面重复键的值,键值对都可以为null。

3、常用API

方法名 解释
V put(K key,V value) 添加元素
V remove(Object key) 根据键删除键值对元素
void clear() 清空所有的键值对元素
int size() 集合的长度,集合中键值对的个数
boolean containsKey(Object key) 判断集合是否包含指定的键
boolean containsValue(Object value) 判断集合是否包含指定的值
boolean isEmpty() 判断集合是否为空

4、HashMap 用的最多

元素按照键是无序,不重复,无索引,值不做要求(可以重复)

-实战根据key求value
在这里插入图片描述

import java.util.HashMap;
import java.util.Map;

public class ClassStructure {
    
    
    public static void main(String[] args) {
    
    
        Map<Integer,String> map = new HashMap<>();
        map.put(1,"数学");
        map.put(2,"语文");
        map.put(3,"英语");
        map.put(4,"物理");
        map.put(5,"政治");
        String str = map.get(1);
        System.out.println(str);
        String str1 = map.get(3);
        System.out.println(str1);
    }
}

5、LinkedHashMap

元素按照键是有序,不重复,无索引,值不做要求

  • 实战 判断key是否存在
    在这里插入图片描述
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

public class ClassStructure {
    
    
    public static void main(String[] args) {
    
    
        Map<Integer,String> map = new LinkedHashMap<>();
        map.put(1,"数学");
        map.put(2,"语文");
        map.put(3,"英语");
        map.put(4,"物理");
        map.put(5,"政治");
        boolean str = map.containsKey(1);
        System.out.println(str);
        boolean str1 = map.containsKey(6);
        System.out.println(str1);
    }
}

6、TreeMap

元素按照建是排序,不重复,无索引的,值不做要求

  • 实战 参考TreeSet
    Set系列集合的底层就是Map实现的,只是Set集合中的元素只要键数据

猜你喜欢

转载自blog.csdn.net/walykyy/article/details/126665050
今日推荐