本篇主讲 Set Map Collections Lambda表达式.
1.Set集合
1.1Set集合概述和特点
- Set集合的特点
- 元素存取无序
- 没有索引、只能通过迭代器或增强for循环遍历
- 不能存储重复元素
- Set集合的基本使用
public class SetDemo {
public static void main(String[] args) {
//创建集合对象
Set<String> set = new HashSet<String>();
//添加元素
set.add("hello");
set.add("hadoop");
set.add("java");
//不包含重复元素的集合
set.add("java");
//遍历 快捷键 iter(遍历数组或者集合)
for(String s : set) {
System.out.println(s);
}
}
}
1.2哈希值【理解】
-
哈希值简介
是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
-
如何获取哈希值
Object类中的public int hashCode():返回对象的哈希码值
-
哈希值的特点
- 同一个对象多次调用hashCode()方法返回的哈希值是相同的
- 默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同
-
获取哈希值的代码
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 int hashCode() {
return 0;
}
}
//测试类
public class HashDemo {
public static void main(String[] args) {
//创建学生对象
Student s1 = new Student("林青霞",30);
//同一个对象多次调用hashCode()方法返回的哈希值是相同的
System.out.println(s1.hashCode()); //1060830840
System.out.println(s1.hashCode()); //1060830840
System.out.println("--------");
Student s2 = new Student("林青霞",30);
//默认情况下,不同对象的哈希值是不相同的
//通过方法重写,可以实现不同对象的哈希值是相同的
System.out.println(s2.hashCode()); //2137211482
System.out.println("--------");
System.out.println("hello".hashCode()); //99162322
System.out.println("world".hashCode()); //113318802
System.out.println("java".hashCode()); //3254818
System.out.println("world".hashCode()); //113318802
System.out.println("--------");
System.out.println("重地".hashCode()); //1179395
System.out.println("通话".hashCode()); //1179395
}
}
1.3HashSet集合概述和特点(记忆)
HashSet集合(Set集合接口的实现类)的特点
- 底层数据结构是哈希表
- 无序
- 没有带索引的方法,所以不能使用普通for循环遍历
- 由于是Set集合,所以是不包含重复元素的集合
public class HashSetDemo01 {
public static void main(String[] args) {
//创建集合对象
HashSet<String> hs = new HashSet<String>();
//添加元素
hs.add("hello");
hs.add("world");
hs.add("java");
hs.add("world");
//遍历
for(String s : hs) {
System.out.println(s);
}
}
}
**补充: 1: 大家要根据实际开发中的需求来确定要是用哪一种集合比较方便, 本着节约
资源,提高效率的思想.**
2: HashSet 集合元素唯一性: 依赖于 equals() 方法 和 hashCode() 方法
1.4LinkedHashSet集合概述和特点
LinkedHashSet(继承了HashSet)集合特点
- 哈希表和链表实现的Set接口,具有可预测的迭代次序
- 由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
- 由哈希表保证元素唯一,也就是说没有重复的元素
可变参数【应用】
-
可变参数介绍
可变参数又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的了
-
可变参数定义格式
修饰符 返回值类型 方法名(数据类型… 变量名) { }
-
可变参数的注意事项
- 这里的变量其实是一个数组
- 如果一个方法有多个参数,包含可变参数,可变参数要放在最后
-
可变参数的基本使用
/**
*
通过代码, 完成如下需求:
* 1. 定义方法getSum(), 用来获取n个整数的和.
* 2. 在main方法中调用getSum()方法.
* 3. 要求: 通过可变参数实现.
*
*
*/
public class TestDemo03 {
public static void main(String[] args) {
int result = getSum(20,20,30,20);
System.out.println("和为:"+result);
}
//定义一个可变参数的方法
public static int getSum(int... arr) { //可变参数 本质就是一个数组
int sum = 0;
for (int i : arr) { //增强for 遍历数组 求和
sum +=i;
}
return sum;
}
}
Map集合概述和特点【记忆】
-
Map集合概述
interface Map<K,V> K:键的类型;V:值的类型
-
Map集合的特点
- 键值对映射关系
- 一个键对应一个值
- 键不能重复,值可以重复
- 元素存取无序
public class MapTest01 {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("科比","瓦妮莎");
map.put("杨过","小龙女");
map.put("嘻嘻","哈哈");
/* Set<String> s = map.keySet(); //将Map中的key封装成set集合 [杨过, 嘻嘻, 科比]
for (String key : s) { //遍历set集合 增强for
String value = map.get(key);
System.out.println(key + "......" + value);
}*/
for (String s1 : map.keySet()) {
System.out.println(s1 + ".." + map.get(s1));
}
//System.out.println(s); //[杨过, 嘻嘻, 科比]
}
}
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() | 集合的长度,也就是集合中键值对的个数 |
public class MapDemo02 {
public static void main(String[] args) {
//创建集合对象
Map<String,String> map = new HashMap<String,String>();
//V put(K key,V value):添加元素
map.put("张无忌","赵敏");
map.put("郭靖","黄蓉");
map.put("杨过","小龙女");
//V remove(Object key):根据键删除键值对元素
// System.out.println(map.remove("郭靖"));
// System.out.println(map.remove("郭襄"));
//void clear():移除所有的键值对元素
// map.clear();
//boolean containsKey(Object key):判断集合是否包含指定的键
// System.out.println(map.containsKey("郭靖"));
// System.out.println(map.containsKey("郭襄"));
//boolean isEmpty():判断集合是否为空
// System.out.println(map.isEmpty());
//int size():集合的长度,也就是集合中键值对的个数
System.out.println(map.size());
//输出集合对象
System.out.println(map);
}
}
Map集合的获取功能
方法介绍
方法名 | 说明 |
---|---|
V get(Object key) | 根据键获取值 |
Set keySet() | 获取所有键的集合 |
Collection values() | 获取所有值的集合 |
Set<Map.Entry<K,V>> entrySet() | 获取所有键值对对象的集合 |
Map集合的遍历(方式1)【应用】
- 遍历思路
- 我们刚才存储的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合
- 把所有的丈夫给集中起来
- 遍历丈夫的集合,获取到每一个丈夫
- 根据丈夫去找对应的妻子
- 我们刚才存储的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合
- 步骤分析
- 获取所有键的集合。用keySet()方法实现
- 遍历键的集合,获取到每一个键。用增强for实现
- 根据键去找值。用get(Object key)方法实现
Map集合的遍历(方式2)【应用】
- 遍历思路
- 我们刚才存储的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合
- 获取所有结婚证的集合
- 遍历结婚证的集合,得到每一个结婚证
- 根据结婚证获取丈夫和妻子
- 我们刚才存储的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合
- 步骤分析
- 获取所有键值对对象的集合
- Set<Map.Entry<K,V>> entrySet():获取所有键值对对象的集合
- 遍历键值对对象的集合,得到每一个键值对对象
- 用增强for实现,得到每一个Map.Entry
- 根据键值对对象获取键和值
- 用getKey()得到键
- 用getValue()得到值
- 获取所有键值对对象的集合
public class TestDemo04 {
public static void main(String[] args) {
//创建集合对象
HashMap<String, Student> map = new HashMap<>();
//2.创建学生对象并且赋值
Student s1 = new Student("科比", 41);
Student s2 = new Student("詹姆斯", 36);
Student s3 = new Student("姚明", 34);
//3. 将学生对象和地址 添加到集合当中
map.put("洛杉矶",s1);
map.put("克利夫兰",s2);
map.put("上海",s3);
//4.遍历集合
//Map#keySet方法获取键的集合
Set<String> keySet = map.keySet();
for (String key : keySet) {
//map#get 根据建 获取值
Student value = map.get(key);
System.out.println(key + " " + value);
}
System.out.println("--------------------------------------------");
//Map#entrySet 遍历键值对的方式获取
Set<Map.Entry<String, Student>> entrySet = map.entrySet();
for (Map.Entry<String, Student> entry : entrySet) {
//entrySet# getKey getValue 方法获取键值
String key = entry.getKey();
Student value = entry.getValue();
System.out.println(key + " " + value);
}
}
}
Collections集合工具类(类似于Arrays)
-
Collections类的作用
是针对集合操作的工具类
-
Collections类常用方法
方法名 说明 public static void sort(List list) 将指定的列表按升序排序 public static void reverse(List<?> list) 反转指定列表中元素的顺序 public static void shuffle(List<?> list) 使用默认的随机源随机排列指定的列表
public class CollectionsDemo01 {
public static void main(String[] args) {
//创建集合对象
List<Integer> list = new ArrayList<Integer>();
//添加元素
list.add(30);
list.add(20);
list.add(50);
list.add(10);
list.add(40);
//public static <T extends Comparable<? super T>> void sort(List<T> list):将指定的列表按升序排序
// Collections.sort(list);
//public static void reverse(List<?> list):反转指定列表中元素的顺序
// Collections.reverse(list);
//public static void shuffle(List<?> list):使用默认的随机源随机排列指定的列表
Collections.shuffle(list);
System.out.println(list);
}
}
集合嵌套之ArrayList嵌套HashMap
案例需求
- 创建一个ArrayList集合,存储三个元素,每一个元素都是HashMap
- 每一个HashMap的键和值都是String,并遍历。
public class ArrayListIncludeHashMapDemo {
public static void main(String[] args) {
//创建ArrayList集合
ArrayList<HashMap<String, String>> array = new ArrayList<HashMap<>>();
//创建HashMap集合,并添加键值对元素
HashMap<String, String> hm1 = new HashMap<>();
hm1.put("孙策", "大乔");
hm1.put("周瑜", "小乔");
//把HashMap作为元素添加到ArrayList集合
array.add(hm1);
HashMap<String, String> hm2 = new HashMap<>();
hm2.put("郭靖", "黄蓉");
hm2.put("杨过", "小龙女");
//把HashMap作为元素添加到ArrayList集合
array.add(hm2);
HashMap<String, String> hm3 = new HashMap<>();
hm3.put("令狐冲", "任盈盈");
hm3.put("林平之", "岳灵珊");
//把HashMap作为元素添加到ArrayList集合
array.add(hm3);
//遍历ArrayList集合
for (HashMap<String, String> hm : array) {
Set<String> keySet = hm.keySet();
for (String key : keySet) {
String value = hm.get(key);
System.out.println(key + "," + value);
}
}
}
}
集合嵌套之HashMap嵌套ArrayList
案例需求
- 创建一个HashMap集合,存储三个键值对元素,每一个键值对元素的键是String,值是ArrayList
- 每一个ArrayList的元素是String,并遍历。
public class HashMapIncludeArrayListDemo {
public static void main(String[] args) {
//创建HashMap集合
HashMap<String, ArrayList<String>> hm = new HashMap<String, ArrayList<String>>();
//创建ArrayList集合,并添加元素
ArrayList<String> sgyy = new ArrayList<String>();
sgyy.add("诸葛亮");
sgyy.add("赵云");
//把ArrayList作为元素添加到HashMap集合
hm.put("三国演义",sgyy);
ArrayList<String> xyj = new ArrayList<String>();
xyj.add("唐僧");
xyj.add("孙悟空");
//把ArrayList作为元素添加到HashMap集合
hm.put("西游记",xyj);
ArrayList<String> shz = new ArrayList<String>();
shz.add("武松");
shz.add("鲁智深");
//把ArrayList作为元素添加到HashMap集合
hm.put("水浒传",shz);
//遍历HashMap集合
Set<String> keySet = hm.keySet();
for(String key : keySet) {
System.out.println(key);
ArrayList<String> value = hm.get(key);
for(String s : value) {
System.out.println("\t" + s);
}
}
}
}
1.Lambda表达式
函数式编程思想概述
函数式思想则尽量忽略面向对象的复杂语法:“强调做什么,而不是以什么形式去做”
而我们要学习的Lambda表达式就是函数式思想的体现
Lambda表达式的标准格式【理解】
-
格式:
(形式参数) -> {代码块}
- 形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可
- ->:由英文中画线和大于符号组成,固定写法。代表指向动作
- 代码块:是我们具体要做的事情,也就是以前我们写的方法体内容
-
组成Lambda表达式的三要素:
- 形式参数,箭头,代码块
Lambda表达式的使用前提
有一个接口
接口中有且仅有一个抽象方法
- 形式参数,箭头,代码块
案例1:
- 练习描述
无参无返回值抽象方法的练习
- 操作步骤
- 定义一个接口(Eatable),里面定义一个抽象方法:void eat();
- 定义一个测试类(EatableDemo),在测试类中提供两个方法
- 一个方法是:useEatable(Eatable e)
- 一个方法是主方法,在主方法中调用useEatable方法
-
//接口
public interface Eatable {
void eat();
}
//实现类
public class EatableImpl implements Eatable {
@Override
public void eat() {
System.out.println("我要吃东西啦.....");
}
}
//测试类
public class EatableDemo {
public static void main(String[] args) {
//在主方法中调用useEatable方法
Eatable e = new EatableImpl();
useEatable(e);
//匿名内部类
useEatable(new Eatable() {
@Override
public void eat() {
System.out.println("我要吃东西啦.....");
}
});
//Lambda表达式
useEatable(() -> {
System.out.println("我要吃东西啦.....");
});
}
private static void useEatable(Eatable e) {
e.eat();
}
}
### Lambda表达式练习2【】
- 练习描述
有参无返回值抽象方法的练习
/**
* 添加用户接口
*/
public interface AddUser {
void add(String name);
}
/**
* 测试类
*/
public class TestAddUser {
public static void main(String[] args) {
// 匿名内部类写法
addUser(new AddUser() {
@Override
public void add(String name) {
System.out.println(name);
System.out.println("匿名内部类添加成功啦~~!!!!");
}
});
//Lambda表达式写法
addUser((name)->{
System.out.println(name);
System.out.println("Lambda表达式方法添加成功啦~~!@!");
});
}
private static void addUser(AddUser addUser) {
addUser.add("科比");
}
}
### Lambda表达式练习3【应用】
有参有返回值抽象方法的练习
/**
* 接口
*/
public interface AddInt {
int add(int x, int y);
}
/**
测试类
*/
public class TestDemo01 {
public static void main(String[] args) {
//匿名内部类
addInt(new AddInt() {
@Override
public int add(int x, int y) {
System.out.println("匿名内部类方法.......");
return x + y;
}
},20,30);
//Lambda表达式方法
addInt((x,y) ->{
System.out.println("Lambda内部类方法.......");
return x + y;
},200,30);
}
public static void addInt(AddInt a,int x, int y){
int sum = a.add(x, y);
System.out.println(sum);
}
}
Lambda表达式的省略模式【应用】
- 省略的规则
- 参数类型可以省略。但是有多个参数的情况下,不能只省略一个
- 如果参数有且仅有一个,那么小括号可以省略
- 如果代码块的语句只有一条,可以省略大括号和分号,和return关键字
public class TestAddUser {
public static void main(String[] args) {
//Lambda表达式写法
addUser(name -> System.out.println(name));
}
private static void addUser(AddUser addUser) {
addUser.add("科比");
}
}
//参数类型可以省略。但是有多个参数的情况下,不能只省略一个
public class TestDemo01 {
public static void main(String[] args) {
//Lambda表达式方法
addInt(( x,y) ->{
return x + y;
},200,30);
}
public static void addInt(AddInt a,int x, int y){
int sum = a.add(x, y);
System.out.println(sum);
}
}