一、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 ClassSructure { 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集合中的元素只要键数据