Set集合实现类特点
import java.util.HashSet;
import java.util.Set;
public class Test {
public static void main(String[] args) {
// 看看Set系列集合的特点: HashSet LinkedHashSet TreeSet
//
Set<String> sets = new HashSet<>(); // 一行经典代码 无序不重复,无索引
// Set sets = new LinkedHashSet<>(); // 有序 不重复 无索引
sets.add("MySQL");
sets.add("MySQL");
sets.add("Java");
sets.add("Java");
sets.add("HTML");
sets.add("HTML");
sets.add("SpringBoot");
sets.add("SpringBoot");
System.out.println(sets);
}
}
HashSet集合底层采取哈希表存储的数据。
哈希表是一种对于增删改查数据性能都较好的结构。
哈希值- -是JDK根据对象的地址,按照某种规则算出来的int类型的数值。
Object类的API
public class Test {
public static void main(String[] args) {
// 目标:学会获取对象的哈希值,并确认一下
String name = "haut";
System.out.println(name.hashCode());
System.out.println(name.hashCode());
String name1 = "haut1";
System.out.println(name1.hashCode());
System.out.println(name1.hashCode());
}
}
对象的哈希值特点
HashSet1.7版本原理解析(数组+链表)
JDK1. .8版本HashSet原理解析(数组+链表+红黑树)
底层结构:哈希表(数组、链表、红黑树的结合体)
当挂在元素下面的数据过多时,查询性能降低,从JDK8开始后,当链表长度超过8的时候,自动转换为红黑树。
结论:如果希望Set集合认为2个内容一样的对象是重复的,必须重写对象的hashCode()和equals(方法
LinkedHashSet集合概述和特点
TreeSet集合概述和特点
注意: TreeSet集合是一定要排序的,可以将元素按照指定的规则进行排序。
TreeSet集合默认的规则
结论:想要使用TreeSet存储自定义类型,需要制定排序规则
自定义排序规则
TreeSet集合存储对象的的时候有2种方式可以设计自定义比较规则
方式一
方式二
两种方式中,关于返回值的规则:
注意:如果TreeSet集合存储的对象有实现比较规则,集合也自带比较器,默认使用集合自带的比较器排序。
可变参数
可变参数的作用
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
sum(); // 1、不传参数
sum(10); // 2、可以传输一个参数
sum(10, 20, 30); // 3、可以传输多个参数
sum(new int[]{10, 20, 30, 40, 50}); // 4、可以传输一个数组
}
/**
注意:一个形参列表中只能有一个可变参数,可变参数必须放在形参列表的最后面
* @param nums
*/
public static void sum( int...nums){
// 注意:可变参数在方法内部其实就是一个数组。 nums
System.out.println("元素个数:" + nums.length);
System.out.println("元素内容:" + Arrays.toString(nums));
}
}
可变参数的注意事项
Collections集合工具类
java.utils.Collections:是集合工具类
作用: Collections并不属于集合, 是用来操作集合的工具类。
Collections常用的API
方法名称 | 说明 |
---|---|
public static boolean addAll(Collection super T> C, T… elements) | 给集合对象批量添加元素 |
public static void shuffle(List> list) | 打乱List集合元素的顺序 |
Collections排序相关API
使用范围:只能对于List集合的排序。
排序方式1:
方法名称 | 说明 |
---|---|
public static void sort(List list) | 将集合中元素按照默认规则排序 |
注意:本方式不可以直接对自定义类型的List集合排序,除非自定义类型实现了比较规则Comparable接口。
排序方式2:
方法名称 | 说明 |
---|---|
public static void sort(List list, Comparator super T> c) | 将集合中元素按照指定规则排序 |
public class Test {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
//names.add("楚留香");
//names.add("胡铁花");
//names.add("张无忌");
//names.add("陆小凤");
Collections.addAll(names, "楚留香","胡铁花", "张无忌","陆小凤");
System.out.println(names);
// 2、public static void shuffle(List> list) :打乱集合顺序。
Collections.shuffle(names);
System.out.println(names);
// 3、 public static void sort(List list):将集合中元素按照默认规则排序。 (排值特性的元素)
List<Integer> list = new ArrayList<>();
Collections.addAll(list, 12, 23, 2, 4);
System.out.println(list);
Collections.sort(list);
System.out.println(list);
}
}
Map集合概述和使用
Map集合整体格式
import java.util.LinkedHashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
// 1、创建一个Map集合对象
// Map maps = new HashMap<>(); // 一行经典代码
Map<String, Integer> maps = new LinkedHashMap<>();
maps.put("鸿星尔克", 3);
maps.put("Java", 1);
maps.put("枸杞", 100);
maps.put("Java", 100); // 覆盖前面的数据
maps.put(null, null);
System.out.println(maps);
}
}
Map集合体系特点
Map集合实现类特点
Map集合
Map是双列集合的祖宗接口,它的功能是全部双列集合都可以继承使用的。
Map API如下:
方法名称 | 说明 |
---|---|
V put(K key,V value) | 添加元素 |
V remove(0bject key) | 根据键删除键值对元素 |
void clear( ) | 移除所有的键值对元素 |
boolean containsKey(object key) | 判断集合是否包含指定的键 |
boolean containsValue(0bject value ) | 判断集合是否包含指定的值 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中键值对的个数 |
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test {
public static void main(String[] args) {
// 1.添加元素: 无序,不重复,无索引。
Map<String , Integer> maps = new HashMap<>();
maps.put("iphoneX",10);
maps.put("娃娃",20);
maps.put("iphoneX",100);// Map集合后面重复的键对应的元素会覆盖前面重复的整个元素!
maps.put("huawei",100);
maps.put("生活用品",10);
maps.put("手表",10);
// {huawei=100, 手表=10, 生活用品=10, iphoneX=100, 娃娃=20}
System.out.println(maps);
// 2.清空集合
// maps.clear();
// System.out.println(maps);
// 3.判断集合是否为空,为空返回true ,反之!
System.out.println(maps.isEmpty());
// 4.根据键获取对应值:public V get(Object key)
Integer key = maps.get("huawei");
System.out.println(key);
System.out.println(maps.get("生活用品")); // 10
System.out.println(maps.get("生活用品2")); // null
// 5.根据键删除整个元素。(删除键会返回键的值)
System.out.println(maps.remove("iphoneX"));
System.out.println(maps);
// 6.判断是否包含某个键 ,包含返回true ,反之
System.out.println(maps.containsKey("娃娃")); // true
System.out.println(maps.containsKey("娃娃2")); // false
System.out.println(maps.containsKey("iphoneX")); // false
// 7.判断是否包含某个值。
System.out.println(maps.containsValue(100)); //
System.out.println(maps.containsValue(10)); //
System.out.println(maps.containsValue(22)); //
// {huawei=100, 手表=10, 生活用品=10, 娃娃=20}
// 8.获取全部键的集合:public Set keySet()
Set<String> keys = maps.keySet();
System.out.println(keys);
System.out.println("------------------------------");
// 9.获取全部值的集合:Collection values();
Collection<Integer> values = maps.values();
System.out.println(values);
// 10.集合的大小
System.out.println(maps.size()); // 4
// 11.合并其他Map集合。(拓展)
Map<String , Integer> map1 = new HashMap<>();
map1.put("java1", 1);
map1.put("java2", 100);
Map<String , Integer> map2 = new HashMap<>();
map2.put("java2", 1);
map2.put("java3", 100);
map1.putAll(map2); // 把集合map2的元素拷贝一份到map1中去
System.out.println(map1);
System.out.println(map2);
}
}
方式一 - - 键找值
键找值涉及到的API:
方法名称 | 说明 |
---|---|
Set keySet() | 获取所有键的集合 |
V get(Object key) | 根据键获取值 |
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test {
public static void main(String[] args) {
Map<String , Integer> maps = new HashMap<>();
// 1.添加元素: 无序,不重复,无索引。
maps.put("娃娃",30);
maps.put("iphoneX",100);
maps.put("huawei",1000);
maps.put("生活用品",10);
maps.put("手表",10);
System.out.println(maps);
// maps = {huawei=1000, 手表=10, 生活用品=10, iphoneX=100, 娃娃=30}
// 1、键找值:第一步:先拿到集合的全部键。
Set<String> keys = maps.keySet();
// 2、第二步:遍历每个键,根据键提取值
for (String key : keys) {
int value = maps.get(key);
System.out.println(key + "===>" + value);
}
}
}
方式二 – 键值对
键值对涉及到的API:
方法名称 | 说明 |
---|---|
Set |
获取所有键值对对象的集合 |
K getKey() | 获得键 |
V getValue() | 获取值 |
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test {
public static void main(String[] args) {
Map<String , Integer> maps = new HashMap<>();
// 1.添加元素: 无序,不重复,无索引。
maps.put("娃娃",30);
maps.put("iphoneX",100);
maps.put("huawei",1000);
maps.put("生活用品",10);
maps.put("手表",10);
System.out.println(maps);
// maps = {huawei=1000, 手表=10, 生活用品=10, iphoneX=100, 娃娃=30}
// 1、把Map集合转换成Set集合
Set<Map.Entry<String, Integer>> entries = maps.entrySet();
// 2、开始遍历
for(Map.Entry<String, Integer> entry : entries){
String key = entry.getKey();
int value = entry.getValue();
System.out.println(key + "====>" + value);
}
}
}
方式三 – lambda表达式
得益于JDK 8开始的新技术Lambda表达式,提供了一种更简单、更直接的遍历集合的方式。
Map结合Lambda遍历的API
方法名称 | 说明 |
---|---|
default void forEach(Biconsumer super K, ? super v> action) | 结合lambda遍历Map集合 |
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
public class Test {
public static void main(String[] args) {
Map<String , Integer> maps = new HashMap<>();
// 1.添加元素: 无序,不重复,无索引。
maps.put("娃娃",30);
maps.put("iphoneX",100);// Map集合后面重复的键对应的元素会覆盖前面重复的整个元素!
maps.put("huawei",1000);
maps.put("生活用品",10);
maps.put("手表",10);
System.out.println(maps);
maps.forEach((k, v) -> {
System.out.println(k + "--->" + v);
});
}
}
HashMap
(实际上:Set系列集合的底层就是Map实现的,只是Set集合中的元素只要键数据,不要值数据而已。)
import com.itheima.d1_collection_set.Student;
import java.util.HashMap;
import java.util.Map;
public class HashMapDemo {
public static void main(String[] args) {
// Map集合是根据键去除重复元素
Map<Student, String> maps = new HashMap<>();
Student s1 = new Student("无恙", 20, '男');
Student s2 = new Student("无恙", 20, '男');
Student s3 = new Student("周雄", 21, '男');
maps.put(s1, "北京");
maps.put(s2, "上海");
maps.put(s3, "广州");
System.out.println(maps);
}
}
LinkenHashMap
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeSet;
/**
目标:认识Map体系的特点:按照键无序,不重复,无索引。值不做要求。
*/
public class LinkedHashMapDemo {
public static void main(String[] args) {
// 1、创建一个Map集合对象
Map<String, Integer> maps = new LinkedHashMap<>();
maps.put("鸿星尔克", 3);
maps.put("Java", 1);
maps.put("枸杞", 100);
maps.put("Java", 100); // 覆盖前面的数据
maps.put(null, null);
System.out.println(maps);
}
}
TreeMap
TreeMap集合自定义排序规则有2种
public class Apple implements Comparable<Apple>{
private String name;
private String color;
private double price;
private int weight;
public Apple() {
}
public Apple(String name, String color, double price, int weight) {
this.name = name;
this.color = color;
this.price = price;
this.weight = weight;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
@Override
public String toString() {
return "Apple{" +
"name='" + name + '\'' +
", color='" + color + '\'' +
", price=" + price +
", weight=" + weight +
'}';
}
/**
方式一:类自定义比较规则
o1.compareTo(o2)
* @param o
* @return
*/
@Override
public int compareTo(Apple o) {
// 按照重量进行比较的
return this.weight - o.weight ; // 去重重量重复的元素
// return this.weight - o.weight >= 0 ? 1 : -1; // 保留重量重复的元素
}
}
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
public class TreeMapDemo3 {
public static void main(String[] args) {
Map<Integer, String> maps1 = new TreeMap<>();
maps1.put(13 , "王麻子");
maps1.put(1 , "张三");
maps1.put(3 , "县长");
System.out.println(maps1);
// TreeMap集合自带排序。 可排序 不重复(只要大小规则一样就认为重复) 无索引
Map<Apple, String> maps2 = new TreeMap<>(new Comparator<Apple>() {
@Override
public int compare(Apple o1, Apple o2) {
return Double.compare(o2.getPrice() , o1.getPrice()); // 按照价格降序排序!
}
});
maps2.put(new Apple("红富士", "红色", 9.9, 500), "山东" );
maps2.put(new Apple("青苹果", "绿色", 15.9, 300), "广州");
maps2.put(new Apple("绿苹果", "青色", 29.9, 400), "江西");
maps2.put(new Apple("黄苹果", "黄色", 9.8, 500), "湖北");
System.out.println(maps2);
}
}
需求
分析
import java.util.*;
public class MapTest4 {
public static void main(String[] args) {
// 1、要求程序记录每个学生选择的情况。
// 使用一个Map集合存储。
Map<String, List<String>> data = new HashMap<>();
// 2、把学生选择的数据存入进去。
List<String> selects = new ArrayList<>();
Collections.addAll(selects, "A", "C");
data.put("罗勇", selects);
List<String> selects1 = new ArrayList<>();
Collections.addAll(selects1, "B", "C" , "D");
data.put("胡涛", selects1);
List<String> selects2 = new ArrayList<>();
Collections.addAll(selects2 , "A", "B", "C" , "D");
data.put("刘军", selects2);
System.out.println(data);
// 3、统计每个景点选择的人数。
Map<String, Integer> infos = new HashMap<>(); // {}
// 4、提取所有人选择的景点的信息。
Collection<List<String>> values = data.values();
System.out.println(values);
// values = [[A, B, C, D], [B, C, D], [A, C]]
// value
for (List<String> value : values) {
for (String s : value) {
// 有没有包含这个景点
if(infos.containsKey(s)){
infos.put(s, infos.get(s) + 1);
}else {
infos.put(s , 1);
}
}
}
System.out.println(infos);
}
}
不可变集合,就是不可被修改的集合。集合的数据项在创建的时候提供,并且在整个生命周期中都不可改变。否则报错。
如果某个数据不能被修改,把它防御性地拷贝到不可变集合中是个很好的实践。或者当集合对象被不可信的库调用时,不可变形式是安全的。
在List、Set、Map接口中,都存在of方法,可以创建一个不可变的集合。
方法名称 | 说明 |
---|---|
static List of(E…elements) | 创建一个具有指定元素的List集合对象 |
static Set of(E…elements) | 创建一个具有指定元素的Set集合对象 |
static |
创建一个具有指定元素的Map集合对象 |
这个集合不能添加,不能删除,不能修改。 |
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class CollectionDemo {
public static void main(String[] args) {
// 1、不可变的List集合
List<Double> lists = List.of(569.5, 700.5, 523.0, 570.5);
// lists.add(689.0);
// lists.set(2, 698.5);
// System.out.println(lists);
double score = lists.get(1);
System.out.println(score);
// 2、不可变的Set集合
Set<String> names = Set.of("迪丽热巴", "迪丽热九", "马尔扎哈", "卡尔眨巴" );
// names.add("三少爷");
System.out.println(names);
// 3、不可变的Map集合
Map<String, Integer> maps = Map.of("huawei",2, "Java开发", 1 , "手表", 1);
// maps.put("衣服", 3);
System.out.println(maps);
}
}