HashSet集合
HashSet集合概述和特点
- 底层数据结构是哈希表
- 存取无序
- 不可以存储重复元素
- 没有索引,不能使用普通for循环遍历
HashSet集合的基本应用
存储字符串并遍历
package com.itheima_03;
import java.util.HashSet;
public class HashSetDemo {
public static void main(String[] args) {
// 创建集合对象
HashSet<String> set = new HashSet<>();
set.add("hello");
set.add("world");
set.add("java");
set.add("world");
for (String s : set
) {
System.out.println(s);
}
}
}
哈希值【理解】
- 哈希值简介
是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值 - 如何获取哈希值
Object类中的public interesting hashCode():返回对象的哈希码值 - 哈希值的特点
- 同一个对象多次调用hashCode()方法返回的哈希值是相同的
- 默认情况,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同。
哈希表结构【理解】
- JDK1.8以前
数组+链表 - JDK1.8以后
- 节点个数少于等于8个
数组+链表 - 节点个数多于8个
数组+红黑树
- 节点个数少于等于8个
HashSet集合存储学生对象并遍历【应用】
- 案例需求
- 创建一个存储学生对象的集合,存储多个学生对象,使用程序实现在控制台遍历该集合
- 要求:学生对象的成员变量值相同,我们就认为是同一对象 。
- 代码实现
学生类
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
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 boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
if (age != student.age) return false;
return name != null ? name.equals(student.name) : student.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
}
测试类
public class HashSetDemo02 {
public static void main(String[] args) {
//创建HashSet集合对象
HashSet<Student> hs = new HashSet<Student>();
//创建学生对象
Student s1 = new Student("林青霞", 30);
Student s2 = new Student("张曼玉", 35);
Student s3 = new Student("王祖贤", 33);
Student s4 = new Student("王祖贤", 33);
//把学生添加到集合
hs.add(s1);
hs.add(s2);
hs.add(s3);
hs.add(s4);
//遍历集合(增强for)
for (Student s : hs) {
System.out.println(s.getName() + "," + s.getAge());
}
}
}
- 总结
HashSet集合存储自定义类型元素,要想实现元素的唯一,要求必须重写hashCode方法和equals方法。
Map集合
Map集合概述和特点【理解】
- Map集合概述
interface Map<K,V> K:键的类型;V:值的类型
- Map集合的特点
- 双列集合,一个键对应一个值
- 键不可重复,值可以重复
- Map集合的基本使用
package com.itheima_05;
import java.util.HashMap;
public class MapDemo01 {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("itheima001", "林青霞");
map.put("itheima002", "张曼玉");
map.put("itheima003", "王祖贤");
map.put("itheima004", "柳岩");
// 输出集合对象
System.out.println(map);
}
}
Map集合的基本功能【应用】
- 方法介绍
方法名 | 说明 |
---|---|
V put(K key,V value) | 添加元素 |
V remove(Object key) | 根据键删除键值对元素 |
void clear() | 移除所有的键值对元素 |
boolean containsKey(Object key) | 判断集合是否包含指定的键 |
boolean containsValue(Object value) | 判断集合是否包含指定的值 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中键值对的个数 |
- 示例代码
package com.itheima_05;
import java.util.HashMap;
public class MapDemo02 {
public static void main(String[] args) {
// 创建集合对象
HashMap<String, String> map = new HashMap<>();
map.put("张无忌", "赵敏");
map.put("郭靖", "黄蓉");
map.put("杨过", "小龙女");
System.out.println(map.size());
// 输出集合对象
System.out.println(map);
}
}
Map集合的获取功能【应用】
- 方法介绍
方法名 | 说明 |
---|---|
V get(Object key) | 根据键获取值 |
Set keySet() | 获取所有键的集合 |
Collection values() | 获取所有值的集合 |
Set<Map.Entry<K,V>> entrySet() | 获取所有键值对对象的集合 |
- 示例代码
package com.itheima_06;
import java.util.Collection;
import java.util.HashMap;
public class MapDemo03 {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
// 添加元素
map.put("张无忌", "赵敏");
map.put("郭靖", "黄蓉");
map.put("杨过", "小龙女");
Collection<String> values = map.values();
for (String value : values
) {
System.out.println(value);
}
}
}
Map集合的遍历(方式1)【应用】
- 遍历思路
- 我们刚才存储的元素都是成对出现的,所以我们把Map看成一个夫妻对的集合
- 把所有的丈夫给集中起来
- 遍历丈夫的集合,获取到每一个丈夫
- 根据丈夫去找对应的妻子
- 我们刚才存储的元素都是成对出现的,所以我们把Map看成一个夫妻对的集合
- 步骤分析
- 获取所有键的集合,用keySet()方法实现
- 遍历键的集合,获取到每一个键。用增强for实现
- 根据键去找值。用get(Object key)方法实现
- 代码实现
package com.itheima_06;
import java.util.HashMap;
import java.util.Set;
public class MapDemo01 {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
// 添加元素栈
map.put("张无忌", "赵敏");
map.put("郭靖", "黄蓉");
map.put("杨过", "小龙女");
// 获取所有键的集合
Set<String> keySet = map.keySet();
// 遍历键的集合,获取到每一个键,用增强for实现
for (String key : keySet
) {
String value = map.get(key);
System.out.println(key + "," + value);
}
}
}
Map集合的遍历(方式2)【应用】
- 遍历思路
- 我们刚才村春的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合
- 获取所有结婚证的集合
- 遍历结婚证的集合,得到每一个结婚证
- 根据结婚证获取丈夫和妻子
- 我们刚才村春的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合
- 步骤分析
- 获取所有键值对对象的集合
- Set<Map.Entry<K,V>> entrySet():获取所有键值对对象的集合
- 遍历键值对对象的集合,得到每一个键值对对象
- 用增强for实现,得到每一个键值对对象
-用增强for实现,得到每一个Map.Entry - 根据键值对对象获取键和值
- 用getKey()得到键
- 用getValue()得到值
- 用增强for实现,得到每一个键值对对象
- 获取所有键值对对象的集合
- 代码实现
package com.itheima_07;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo02 {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("张无忌", "赵敏");
map.put("郭靖", "黄蓉");
map.put("杨过", "小龙女");
// 获取所有键值对对象的集合
Set<Map.Entry<String, String>> entrySet = map.entrySet();
for (Map.Entry<String, String> me : entrySet
) {
// 根据键值对对象获取键和值
String key = me.getKey();
String value = me.getValue();
System.out.println(key + "," + value);
}
}
}
HashMap集合
HashMap集合概述和特点【理解】
- HashMap底层是哈希表结构
- 依赖hashCode方法和equals方法保证键的唯一
- 如果键要存储的是自定义对象,需要重写hashCode和equals方法
HashMap集合应用案例【应用】
- 案例需求
- 创建一个HashMap集合,键是学生对象(Student),值是居住地(String),存储多个元素 并遍历
- 要求保证键的唯一性:如果学生对象的成员变量值相同,我们就认为是同一个对象。
- 代码实现
学生类
package com.itheima_08;
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
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 boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
if (age != student.age) return false;
return name != null ? name.equals(student.name) : student.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
}
测试类
package com.itheima_08;
import java.util.HashMap;
import java.util.Set;
public class HashMapDemo {
public static void main(String[] args) {
HashMap<Student, String> hm = new HashMap<Student, String>();
// 创建学生对象
Student s1 = new Student("林青霞", 30);
Student s2 = new Student("张曼玉", 35);
Student s3 = new Student("王祖贤", 33);
Student s4 = new Student("王祖贤", 33);
// 把学生添加到集合
hm.put(s1, "西安");
hm.put(s2, "武汉");
hm.put(s3, "郑州");
hm.put(s4, "北京");
// 遍历集合
Set<Student> keySet = hm.keySet();
for (Student key : keySet) {
String value = hm.get(key);
System.out.println(key.getName() + "," + key.getAge() + "," + value);
}
}
}
HashMap集合
HashMap集合概述和特点【理解】
- HashMap底层是哈希表结构的
- 依赖hashCode方法和equals方法保证键的唯一
- 如果键要存储的是自定义对象,需要重写hashCode和equals方法
HashMap集合应用案例【应用】
- 案例需求
- 创建一个HashMap集合,键是学生对象(Student),值是居住地(Sstring),村春多个元素并遍历。
- 要求保证键的唯一性:如果学生对象的成员变量值相同,我们就认为是同一个对象
- 代码实现
学生类
package com.itheima_09;
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
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 boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return name != null ? name.equals(student.name) : student.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
}
测试类
package com.itheima_09;
import java.util.HashMap;
import java.util.Set;
public class HashMapDemo {
public static void main(String[] args) {
HashMap<Student, String> hm = new HashMap<>();
Student s1 = new Student("林青霞",30);
Student s2 = new Student("张曼玉",35);
Student s3 = new Student("王祖贤",33);
Student s4 = new Student("王祖贤",33);
// 把学生添加到集合
hm.put(s1,"西安");
hm.put(s2,"武汉");
hm.put(s3,"郑州");
hm.put(s4,"北京");
// 遍历集合
Set<Student> keySet = hm.keySet();
for (Student key:keySet
) {
String value = hm.get(key);
System.out.println(key.getName()+","+key.getAge()+","+value);
}
}
}
TreeMap集合
TreeMap集合概述和特点
- TreeMap底层是红黑树结构
- 依赖自然排序或者比较器排序,对键进行排序
- 如果键存储的是自定义对象,需要实现Comparable接口或者在创建TreeMap对象时候给出比较器排序规则
TreeMap集合应用案例【应用】
- 案例需求
- 创建一个TreeMap集合,键是学生对象(Student),值是籍贯(String),学生属性姓名和年龄,按照年龄进行排序并遍历
- 要求按照学生年龄进行排序,如果年龄相同则按照姓名进行排序
- 代码实现
学生类
package com.itheima_10;
public class Student implements Comparable<Student> {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
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{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student o) {
// 按照年龄进行排序
int result = o.getAge() - this.getAge();
// 次要条件,按照姓名排序
result = result == 0 ? o.getName().compareTo(this.getName()) : result;
return result;
}
}
测试类
package com.itheima_10;
import java.util.TreeMap;
public class Test1 {
public static void main(String[] args) {
// 创建TreeMap集合对象
TreeMap<Student, String> tm = new TreeMap<>();
// 创建学生对象
Student s1 = new Student("xiaohei", 20);
Student s2 = new Student("dapang", 22);
Student s3 = new Student("xiaomei", 22);
tm.put(s1, "江苏");
tm.put(s2, "北京");
tm.put(s3, "天津");
tm.forEach(
(Student key, String value) -> {
System.out.println(key + "--------" + value);
}
);
//
}
}
可变参数
- 可变参数介绍
- 可变参数又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的了
- 方法的参数类型已经确定,个数不确定,我们可以使用可变参数
- 可变参数定义格式
修饰符 返回值类型 方法名(数据类型… 变量名){}
- 可变参数的注意事项
- 这里的变量其实是一个数组
- 如果一个方法有多个参数,包括可变参数,可变参数要放在最后
package com.itheima_11;
public class ArgsDemo01 {
public static void main(String[] args) {
System.out.println(sum(10, 20));
System.out.println(sum(10, 20, 30));
System.out.println(sum(10, 20, 30, 40));
System.out.println(sum(10,20,30,40,50));
System.out.println(sum(10,20,30,40,50,60));
System.out.println(sum(10,20,30,40,50,60,70));
System.out.println(sum(10,20,30,40,50,60,70,80,90,100));
}
public static int sum(int... a){
int sum=0;
for (int i :
a) {
sum += i;
}
return sum;
}
}
创建不可变集合
- 方法介绍
- 在List,Set,Map接口中,都存在of方法,可以创建一个不可变的集合
- 这个集合不能添加,不能删除,不能修改
- 但是可以结合集合的带参构造,实现集合的批量添加
- 在Map接口中,还有一个ofEntries方法可以提高代码的阅读性
- 首先会把键值对封装成一个Entry对象,再把这个Entry对象添加到集合当中
- 在List,Set,Map接口中,都存在of方法,可以创建一个不可变的集合
- 示例代码
package com.itheima_11;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class MyVariableParameter4 {
public static void main(String[] args) {
method1();
method2();
method3();
method4();
}
private static void method4(){
Map<String,String> map=Map.ofEntries(
Map.entry("zhangsan","江苏"),
Map.entry("lisi","北京"));
System.out.println(map);
}
private static void method3(){
Map<String,String> map=Map.of("zhangsan","江苏","lisi","北京","wangwu","天津");
System.out.println(map);
}
private static void method2(){
// 传递参数当中,不能存在重复元素
Set<String> set = Set.of("a", "b", "c", "d", "a");
System.out.println(set);
}
private static void method1(){
List<String> lis = List.of("a","b","c","d");
System.out.println(lis);
ArrayList<String> list3 = new ArrayList<>(List.of("a", "b", "c", "d"));
System.out.println(list3);
}
}