Java-Stream的使用
Java-Stream的使用
创建不可变集合
定义
定义:不可变集合即不可以被修改的集合。
不可变集合的应用场景:
- 如果某个数据不能被修改,把它防御性地拷贝到不可变集合中是个很好的实践。
- 当集合对象被不可信的库调用时,不可变形式是安全的。

如上图电脑硬件信息一般都不可变,因此将其放在不可变的集合中。
简单理解:不想让别人修改集合中的内容。
创建不可变集合的书写格式
在List、Set、Map接口中,都存在静态的of方法,可以获取一个不可变的集合。jdk1.9以上才支持
| 方法名称 | 说明 |
|---|---|
| static List of(E…elements) | 创建一个具有指定元素的List集合对象 |
| static Set of(E…elements) | 创建一个具有指定元素的Set集合对象 |
| static <K , V> Map<K,V> of(E…elements) | 创建一个具有指定元素的Map集合对象 |
注意:这个集合不能添加,不能删除,不能修改。
创建不可变的List集合
创建
public class ImmutableOfList {
public static void main(String[] args) {
/**
* 创建不可变的List集合
* "李白","铠","兰陵王","小乔","大乔","孙策","周瑜","诸葛亮"
*/
//一旦创建完成,就不能修改
List<String> list = List.of("李白","铠","兰陵王","小乔","大乔","孙策","周瑜","诸葛亮");
for (String s : list) {
System.out.print(s + " ");
}
}
}

创建不可变集合后,往集合中添加、修改、删除数据则会报UnsupportedOperationException的错如下
import java.util.List;
/**
* @Author LiTeng
* @Date 2023/10/9 10:57
* Version 1.0
* @Description 创建不可变的List集合
*/
public class ImmutableOfList {
public static void main(String[] args) {
/**
* 创建不可变的List集合
* "李白","铠","兰陵王","小乔","大乔","孙策","周瑜","诸葛亮"
*/
//一旦创建完成,就不能修改
List<String> list = List.of("李白","铠","兰陵王","小乔","大乔","孙策","周瑜","诸葛亮");
list.add("lisi");
list.set(0,"lisi");
list.remove("铠");
}
}

创建不可变的Set集合
import java.util.Set;
/**
* @Author LiTeng
* @Date 2023/10/9 10:57
* Version 1.0
* @Description 创建不可变的Set集合
*/
public class ImmutableOfSet {
public static void main(String[] args) {
/**
* 创建不可变的set集合
* "李白","铠","兰陵王","小乔","大乔","孙策","周瑜","诸葛亮"
*/
Set<String> set = Set.of( "李白","铠","兰陵王","小乔","大乔","孙策","周瑜","诸葛亮");
for (String s : set) {
System.out.print(s +" ");
}
}
}

当我们要获取一个不可变的Set集合时,里面的参数一定要保证唯一性,否则报如下的错误
public class ImmutableOfSet { public static void main(String[] args) { Set<String> set = Set.of( "李白","李白","铠","兰陵王","小乔","大乔","孙策","周瑜","诸葛亮"); for (String s : set) { System.out.print(s +" "); } } }
创建不可变的Map集合
import java.util.Map;
import java.util.Set;
/**
* @Author LiTeng
* @Date 2023/10/9 10:58
* Version 1.0
* @Description 创建不可变的Map集合
*/
public class ImmutableOfMap {
public static void main(String[] args) {
/**
* 创建不可变的Map集合
* "李白","铠","兰陵王","小乔","大乔","孙策","周瑜","诸葛亮"
*/
Map<String,String> map = Map.of( "李白","铠","兰陵王","小乔","大乔","孙策","周瑜","诸葛亮");
Set<String> set = map.keySet();
for (String key : set) {
String value = map.get(key);
System.out.println(key + "=" + value);
}
}
}

细节1:键是不能重复的
细节2:Map里面的of方法,参数是有上限的,最多只能传递20个参数,即10个键值对
原因:map中的of方法没有可变的形参
若要创建大于10个键值对的Map不可变的集合,则要用以下的方式:使用Map.ofEntries(Entry<? extends K, ? extends V>... entries)或 Map.copyOf(Map<? extends K, ? extends V> map)方法实现,使用Map.copyOf的前提是jdk的版本必须大于10。
方式一
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @Author LiTeng
* @Date 2023/10/9 10:58
* Version 1.0
* @Description 创建不可变的Map集合,且参数大于20个
*/
public class ImmutableOfMap11 {
public static void main(String[] args) {
Map<String, String> hashMap = new HashMap<>();
hashMap.put("李白","唐朝");
hashMap.put("王安石","宋朝");
hashMap.put("苏轼","宋朝");
hashMap.put("王维","唐朝");
hashMap.put("李治","唐朝");
hashMap.put("李世民","唐朝");
hashMap.put("诸葛亮","三国");
hashMap.put("周瑜","三国");
hashMap.put("小乔","三国");
hashMap.put("杜甫","唐朝");
hashMap.put("周敦颐","唐朝");
hashMap.put("陶渊明","唐朝");
hashMap.put("曹操","三国");
//获取所有的键值对对象
Set<Map.Entry<String, String>> entries = hashMap.entrySet();
Map<Object, Object> ofEntries = Map.ofEntries(entries.toArray(new Map.Entry[0]));
Set<Map.Entry<Object, Object>> entries1 = ofEntries.entrySet();
for (Map.Entry<Object, Object> entry : entries1) {
System.out.println(entry);
}
System.out.println("=====================");
//把entries变成一个数组
Map.Entry[] arr1 = new Map.Entry[0];
Map.Entry[] array = entries.toArray(arr1);
Map map = Map.ofEntries(array);
Set set = map.entrySet();
for (Object o : set) {
System.out.println(o);
}
}
}

方式二
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @Author LiTeng
* @Date 2023/10/9 10:58
* Version 1.0
* @Description 创建不可变的Map集合,且参数大于20个
*/
public class ImmutableOfMap11 {
public static void main(String[] args) {
Map<String, String> hashMap = new HashMap<>();
hashMap.put("李白","唐朝");
hashMap.put("王安石","宋朝");
hashMap.put("苏轼","宋朝");
hashMap.put("王维","唐朝");
hashMap.put("李治","唐朝");
hashMap.put("李世民","唐朝");
hashMap.put("诸葛亮","三国");
hashMap.put("周瑜","三国");
hashMap.put("小乔","三国");
hashMap.put("杜甫","唐朝");
hashMap.put("周敦颐","唐朝");
hashMap.put("陶渊明","唐朝");
hashMap.put("曹操","三国");
//将hashMap集合转为不可变的集合
Map<String, String> map = Map.copyOf(hashMap);
Set<String> set = map.keySet();
for (String key : set) {
String value = map.get(key);
System.out.println(key + "=" +value);
}
}
}

总结
不可变集合的特点:
定义完成后不可以修改,或者添加、删除
创建不可变集合的方式:
List、 Set、Map接口中,都存在of方法可以创建不可变集合,前提是jdk版本要大于等于9
创建不可变集合要注意的细节:
- List:直接用
- Set:元素不能重复
- Map:元素不能重复、键值对数量最多是10个。
- 超过10个用
ofEntries()方法或者copyOf()方法,使用copyOf()方法的前提是jdk的版必须大于等于10
- 超过10个用
Stream流
练习需求:按照下面的要求完成集合的创建和遍历,创建一个集合,存储多个字符串元素。存储:张无忌、周芷若、赵敏、张强、张三丰
1、把所有以“张”开头的元素存储到新集合中
2、把以“张”开头的,长度为3的元素再存储到新集合中
3、遍历打印最终结果
不使用stream流实现的方式
import java.util.ArrayList;
import java.util.List;
/**
* @Author LiTeng
* @Date 2023/10/9 14:38
* Version 1.0
* @Description 练习案例
*/
public class Test {
/**
* 按照下面的要求完成集合的创建和遍历,创建一个集合,存储多个字符串元素。存储:张无忌、周芷若、赵敏、张强、张三丰
*
* 1、把所有以“张”开头的元素存储到新集合中
*
* 2、把以“张”开头的,长度为3的元素再存储到新集合中
*
* 3、遍历打印最终结果
*/
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏、");
list.add("张强");
list.add("张强");
list.add("张三丰");
//1、把所有以“张”开头的元素存储到新集合中
List<String> list1 = new ArrayList<>();
for (String name : list) {
if (name.startsWith("张")){
list1.add(name);
}
}
//2、把以“张”开头的,长度为3的元素再存储到新集合中
List<String> list2 = new ArrayList<>();
for (String name : list1) {
if (name.length() == 3){
list2.add(name);
}
}
//遍历打印最终结果
System.out.println(list2);
}
}

使用stream流实现
import java.util.ArrayList;
import java.util.List;
/**
* @Author LiTeng
* @Date 2023/10/9 14:47
* Version 1.0
* @Description 练习案例
*/
public class StreamDemo1 {
/**
* 按照下面的要求完成集合的创建和遍历,创建一个集合,存储多个字符串元素。存储:张无忌、周芷若、赵敏、张强、张三丰
*
* 1、把所有以“张”开头的元素存储到新集合中
*
* 2、把以“张”开头的,长度为3的元素再存储到新集合中
*
* 3、遍历打印最终结果
*/
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏、");
list.add("张强");
list.add("张强");
list.add("张三丰");
list.stream().filter(name -> name.startsWith("张")).filter(name -> name.length() == 3).forEach(name -> System.out.println(name));
}
}

Stream流的作用
结合了Lambda表达式,简化集合、数组的操作
Stream流的使用步骤:
1、先得到一条Stream流(流水线),并把数据放上去
2、利用Stream流中的API进行各种操作:
- 中间方法
- 过滤
- 转换
中间方法调用完毕之后,还可从调用其他方法。
- 终结方法
- 统计
- 打印
最后一步(终结方法),调用完毕之后,不能调用其他方法。
| 获取方式 | 方法名 | 说明 |
|---|---|---|
| 单列集合 | default Stream stream() | Collection中的默认方法 |
| 双列集合 | 无 | 无法直接使用stream流 |
| 数组 | public static Stream stream(T]array) | Arrays工具类中的静态方法 |
| 一堆零散数据 | public static Stream of(T… values) | Stream接口中的静态方法 |
说明:
如果使用双列集合(Map),则需要通过KeySet()、或EntrySet()转换成单列集合再获取stream流。
如果使用stream中的of方法获取一堆零散数据,则一堆零散数据的数据类型必须一致。
单列集合
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Stream;
/**
* @Author LiTeng
* @Date 2023/10/9 14:47
* Version 1.0
* @Description 单列集合
*/
public class StreamDemo2 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌","周芷若","赵敏","张翠山","张三丰");
//复杂的写法
Stream<String> stream = list.stream();
stream.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
//形参s是list中的每一个数据
System.out.println(s);
}
});
System.out.println("======================");
//简单的写法
list.stream().forEach(name -> System.out.println(name));
}
}

双列集合
通过KeySet()、或EntrySet()转换成单列集合再获取stream流
KeySet()只能获取到map集合中的keyEntrySet()可以获取到map集合中的key-value键值对
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Stream;
/**
* @Author LiTeng
* @Date 2023/10/9 14:47
* Version 1.0
* @Description 双列集合
*/
public class StreamDemo3 {
public static void main(String[] args) {
Map<String, String> hashMap = new HashMap<>();
hashMap.put("李白","唐朝");
hashMap.put("王安石","宋朝");
hashMap.put("苏轼","宋朝");
hashMap.put("王维","唐朝");
hashMap.put("李治","唐朝");
hashMap.put("李世民","唐朝");
hashMap.put("诸葛亮","三国");
//通过keySet()获取stream流,keySet()只能获取到Ma集合中的key
hashMap.keySet().stream().forEach(key -> System.out.println(key));
System.out.println("============================================");
//通过entrySet()获取stream流,entrySet()能获取到Ma集合中的key-value键值对
hashMap.entrySet().stream().forEach(map -> System.out.println(map));
}
}

数组
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Stream;
/**
* @Author LiTeng
* @Date 2023/10/9 14:47
* Version 1.0
* @Description 数组获取stream流
*/
public class StreamDemo4 {
public static void main(String[] args) {
int arr[] = {1,2,3,4,5,6,7,8,9};
Arrays.stream(arr).forEach(num -> System.out.println(num));
}
}

一堆零散的数据
注意:一堆零散的数据的数据类型必须一致
import java.util.Arrays;
import java.util.stream.Stream;
/**
* @Author LiTeng
* @Date 2023/10/9 14:47
* Version 1.0
* @Description 一堆零散的数据获取stream流
*/
public class StreamDemo5 {
public static void main(String[] args) {
Stream.of(1,2,3,4,5).forEach(num -> System.out.println(num));
Stream.of("A","B","C","D","E").forEach(num -> System.out.println(num));
}
}

Stream接口中静态方法of的细节:
方法的形参是一个可变参数,可以传递一堆零散的数据,也可以传递数组,但是数组必须是引用数据类型的,如果传递基本数据类型,是会把整个数组当做一个元素,放到Stream当中。例如
import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.function.Consumer; import java.util.stream.Stream; /** * @Author LiTeng * @Date 2023/10/9 14:47 * Version 1.0 * @Description 数组获取stream流 */ public class StreamDemo4 { public static void main(String[] args) { int arr[] = {1,2,3,4,5,6,7,8,9}; Stream.of(arr).forEach(num -> System.out.println(num)); } }
Stream流的中间方法
| 名称 | 说明 |
|---|---|
| Stream filter(Predicate<? super T> predicate) | 过滤 |
| Stream limit(long maxSize) | 获取前几个元素 |
| Stream skip(long n) | 跳过前几个元素 |
| Stream distinct() | 元素去重,依赖(hashcode和equals方法) |
| static Stream concat(Stream a, Stream b) | 合并a和b两个流为一个流 |
| Stream map(Function<T , R> mapper) | 转换流中的数据类型 |
注意1:中间方法,返回新的Stream流,原来的Stream流只能使用一次,建议使用链式编程
注意2:修改Stream流中的数据,不会影响原来集合或者数组中的数据
filter
过滤条件,得到最终的数据
package Stream流的中间方法;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
/**
* @Author LiTeng
* @Date 2023/10/9 15:59
* Version 1.0
* @Description filter方法
*/
public class StreamOfFilter {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌","周芷若","赵敏","张翠山","张三丰","张启山");
//1.使用匿名内部类实现
list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
//返回值为true,表示当前数据留下
//返回值为false,表示当前数据舍弃
return s.startsWith("张");
}
}).forEach(name -> System.out.println(name));
System.out.println("===============================");
//2.使用lambda表达式实现
list.stream().filter(name -> name.startsWith("张")).forEach(name -> System.out.println(name));
}
}

limit
获取前几个元素
package Stream流的中间方法;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
/**
* @Author LiTeng
* @Date 2023/10/9 15:59
* Version 1.0
* @Description limit方法
*/
public class StreamOfLimit {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌","周芷若","赵敏","张翠山","张三丰","张启山");
//1.获取前三个数据
list.stream().limit(3).forEach(name -> System.out.println(name));
}
}

skip
跳过前几个元素
package Stream流的中间方法;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @Author LiTeng
* @Date 2023/10/9 15:59
* Version 1.0
* @Description skip方法
*/
public class StreamOfSkip {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌","周芷若","赵敏","张翠山","张三丰","张启山");
//1.获取集合中从第3个到结束的所有数据
list.stream().skip(2).forEach(name -> System.out.println(name));
}
}

distinct
package Stream流的中间方法;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @Author LiTeng
* @Date 2023/10/9 15:59
* Version 1.0
* @Description distinct方法
*/
public class StreamOfDistinct {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌","周芷若","赵敏","张翠山","张三丰","张启山","张无忌");
//1.获取集合中从第3个到结束的所有数据
list.stream().distinct().forEach(name -> System.out.println(name));
}
}

concat
合并两个集合,要合并的集合的数据类型必须一致
package Stream流的中间方法;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;
/**
* @Author LiTeng
* @Date 2023/10/9 15:59
* Version 1.0
* @Description Concat方法
*/
public class StreamOfConcat {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
Collections.addAll(list1,"张无忌","周芷若","赵敏","张翠山","张三丰","张启山");
List<String> list2 = new ArrayList<>();
Collections.addAll(list2,"张良","诸葛亮");
//使用Concat将list1和list2两个集合合并,注意要合并的集合数据类型必须一致
Stream.concat(list1.stream(),list2.stream()).forEach(list -> System.out.println(list));
}
}

map
package Stream流的中间方法;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Stream;
/**
* @Author LiTeng
* @Date 2023/10/9 15:59
* Version 1.0
* @Description Map方法
*/
public class StreamOfMap {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
Collections.addAll(list1, "张无忌-18", "周芷若-19", "赵敏-19", "张翠山-56", "张三丰-65", "张启山-31");
/**
* 需求:取出集合中的年龄数据,如18,19等转换成int类型
*/
//1.使用匿名内部类的写法
//function中的第一个参数为集合的数据类型,第二的参数为要转换成的数据类型,重写的apply方法的形参为集合中的每一个数据,返回值类型为要转换成的数据类型
list1.stream().map(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
String[] split = s.split("-");
Integer age = Integer.valueOf(split[1]);
return age;
}
}).forEach(age -> System.out.println(age));
System.out.println("===========================");
//2.使用lambda表达式实现
list1.stream().map(s -> {
String[] split = s.split("-");
Integer age = Integer.valueOf(split[1]);
return age;
}).forEach(age -> System.out.println(age));
System.out.println("=======================");
//方式二的简写形式
list1.stream().map(s -> Integer.parseInt(s.split("-")[1])).forEach(System.out::println);
}
}

Stream流的终结方法
| 名称 | 说明 |
|---|---|
| void forEach(Consumer action) | 遍历 |
| long count() | 统计 |
| toArray() | 收集流中的数据,放到数组中 |
| collect(Collector collector) | 收集流中的数据,放到集合中 |
forEach方法
package Stream流的终结方法;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Stream;
/**
* @Author LiTeng
* @Date 2023/10/9 15:59
* Version 1.0
* @Description ForEach方法
*/
public class StreamOfForEach {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
Collections.addAll(list1,"张无忌","周芷若","赵敏","张翠山","张三丰","张启山");
//1.匿名内部类的写法
/**
* Consumer的泛型:流中的数据类型
* 重写accept方法的形参:liu中的每一个数据,方法体用于处理逻辑
*/
list1.stream().forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
System.out.println("==================================");
//2.lambda形式实现
list1.stream().forEach(s -> System.out.println(s));
}
}

count方法
package Stream流的终结方法;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
/**
* @Author LiTeng
* @Date 2023/10/9 15:59
* Version 1.0
* @Description Count方法
*/
public class StreamOfCount {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
Collections.addAll(list1,"张无忌","周芷若","赵敏","张翠山","张三丰","张启山");
long count = list1.stream().count();//统计stream集合中数据的个数
System.out.println(count);
}
}

toArray方法
package Stream流的终结方法;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.IntFunction;
import java.util.stream.Stream;
/**
* @Author LiTeng
* @Date 2023/10/9 15:59
* Version 1.0
* @Description toArrary方法
*/
public class StreamOfToArrary {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
Collections.addAll(list1,"张无忌","周芷若","赵敏","张翠山","张三丰","张启山");
//无参数的情况,返回一个Object数组
Object[] array = list1.stream().toArray();
System.out.println(Arrays.toString(array));
System.out.println("=============================");
//有参数的情况
//1.匿名内部类的写法
/**
* IntFunction的泛型:具体的数组类型
* 重写方法apply的形参:流中数据的个数,要与数组的长度保持一致
* apply的返回值类型:具体类型的数组
* 方法体:就是创建数组
*/
String[] array1 = list1.stream().toArray(new IntFunction<String[]>() {
@Override
public String[] apply(int value) {
return new String[value];
}
});
System.out.println(Arrays.toString(array1));
System.out.println("=============================");
//2.lambda表达式的写法
String[] array2 = list1.stream().toArray(value -> new String[value]);
System.out.println(Arrays.toString(array2));
}
}

collect方法
收集数据转换成list集合
通过collect的Collectors.toList()将stream流的数据转换成List集合,会出现重复的数据
package Stream流的终结方法;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.IntFunction;
import java.util.stream.Collectors;
/**
* @Author LiTeng
* @Date 2023/10/9 15:59
* Version 1.0
* @Description Collect方法
*/
public class StreamOfCollectToList {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
Collections.addAll(list1,"张无忌","周芷若","赵敏","张翠山","张三丰","张启山","张翠山");
List<String> list= list1.stream().collect(Collectors.toList());
System.out.println(list);
}
}

收集数据转换成set集合
通过collect的Collectors.toSet()将stream流的数据转换成Set集合,不会出现重复的数据
package Stream流的终结方法;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @Author LiTeng
* @Date 2023/10/9 15:59
* Version 1.0
* @Description Collect方法
*/
public class StreamOfCollectToSet {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
Collections.addAll(list1,"张无忌","周芷若","赵敏","张翠山","张三丰","张启山","张翠山");
Set<String> list= list1.stream().collect(Collectors.toSet());
System.out.println(list);
}
}

收集数据转换成map集合
注意:如果要收集的数据转换成Map集合,则键不能重复,否则会报错
package Stream流的终结方法;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @Author LiTeng
* @Date 2023/10/9 15:59
* Version 1.0
* @Description Collect方法
*/
public class StreamOfCollectToMap {
public static void main(String[] args) {
//注意:如果要收集的数据转换成Map集合,则键不能重复,否则会报错
List<String> list1 = new ArrayList<>();
Collections.addAll(list1,"张无忌-男-18","周芷若-女-19","赵敏-女-19","张翠山-男-49","张三丰-男-65","张启山-男-25");
//1.匿名内部类的写法
/**
* 需求:收集所有男性的数据,将其名字作为key,年龄作为value返回
* 解释:
* toMap()方法:
* 参数一(是一个函数):表示键的生成规则
* 参数二(是一个函数):表示值的生成规则
*
* 解释参数一:
* Function的泛型一:表示流中每一个数据的类型
* Function的泛型二:表示转换成Map集合中键的数据类型
*
* 方法apply的形参:依次表示流中的每一个数据
* 方法体:生成键的代码规则
* 返回值:已生成的键
*
* 解释参数二:
* Function的泛型一:表示流中每一个数据的类型
* Function的泛型二:表示转换成Map集合中值的数据类型
*
* 方法apply的形参:依次表示流中的每一个数据
* 方法体:生成值的代码规则
* 返回值:已生成的值
*
*
*
*
*
*/
Map<String, Integer> map = list1.stream().filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toMap(new Function<String, String>() {
@Override
public String apply(String s) {
return s.split("-")[0];
}
}, new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.parseInt(s.split("-")[2]);
}
}));
System.out.println(map);
System.out.println("===================");
//2.lambda表达式的写法
Map<String, String> collect = list1.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(
Collectors.toMap(key -> key.split("-")[0], value -> value.split("-")[2])
);
System.out.println(collect);
}
}

练习案例
案例一
1、定义一个集合,并添加一些整数 1,2,3,4,5,6,7,8,9,10
2、过滤奇数,只留下偶数。
3、并将结果保存起来
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* @Author LiTeng
* @Date 2023/10/9 19:59
* Version 1.0
* @Description 练习一
*/
public class Test01 {
/**
* 需求:
* 1、定义一个集合,并添加一些整数 1,2,3,4,5,6,7,8,9,10
* 2、过滤奇数,只留下偶数。
* 3、并将结果保存起来
*
*/
public static void main(String[] args) {
// 1、定义一个集合,并添加一些整数 1,2,3,4,5,6,7,8,9,10
List<Integer> list = new ArrayList<>();
Collections.addAll(list,1,2,3,4,5,6,7,8,9,10);
// 2、过滤奇数,只留下偶数。并将结果保存起来
List<Integer> collect = list.stream().filter(num -> num % 2 == 0).collect(Collectors.toList());
System.out.println(collect);
}
}

案例二
创建一个ArrayList集合,并添加以下字符串,字符串中前面是姓名,后面是年龄
“zhangsan,23”
"lisi,24”
"wangwu,25”
保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @Author LiTeng
* @Date 2023/10/9 19:59
* Version 1.0
* @Description 练习二
*/
public class Test02 {
/**
* 需求:
* 创建一个ArrayList集合,并添加以下字符串,字符串中前面是姓名,后面是年龄
* "zhangsan,23"
* "lisi,24”
* "wangwu,25”
* 保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
*/
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list, "zhangsan,23","lisi,24","wangwu,25");
Map<String, Integer> collect = list.stream().filter(p -> Integer.parseInt(p.split(",")[1]) >= 24)
.collect(Collectors.toMap(key -> key.split(",")[0], value -> Integer.parseInt(value.split(",")[1])));
System.out.println(collect);
}
}

案例三
现在有两个ArrayList集合,第一个集合中:存储6名男演员的名字和年龄。第二个集合中:存储6名女演员的名字和年龄。
姓名和年龄中间用逗号隔开。比如:张三,23
要求完成如下的操作:
1,男演员只要名字为3个字的前两人
2,女演员只要姓杨的,并且不要第一个
3,把过滤后的男演员姓名和女演员姓名合并到一起
4,将上一步的演员信息封装成Actor对象。
5,将所有的演员对象都保存到List集合中。
备注:演员类Actor,属性只有一个: name,age
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @Author LiTeng
* @Date 2023/10/9 19:59
* Version 1.0
* @Description 练习三
*/
public class Test03 {
/**
* 需求:
* 现在有两个ArrayList集合,
* 第一个集合中:存储6名男演员的名字和年龄。第二个集合中:存储6名女演员的名字和年龄。
* 姓名和年龄中间用逗号隔开。比如:张三,23
* 要求完成如下的操作:
* 1,男演员只要名字为3个字的前两人
* 2,女演员只要姓杨的,并且不要第一个
* 3,把过滤后的男演员姓名和女演员姓名合并到一起
* 4,将上一步的演员信息封装成Actor对象。
* 5,将所有的演员对象都保存到List集合中。
* 备注:演员类Actor,属性只有一个: name,age
*
*/
public static void main(String[] args) {
List<String> actors1 = new ArrayList<>();
List<String> actors2 = new ArrayList<>();
Collections.addAll(actors1,"白眉鹰王,40","张无忌,23","张翠山,45","张三丰,69","谢逊,46","杨逍,43");
Collections.addAll(actors2,"赵敏,23","周芷若,23","杨不悔,25","杨颖,22","杨超越,26","杨幂,26");
List<String> actor1 = actors1.stream().filter(actor -> actor.split(",")[0].length() >= 3).limit(2).collect(Collectors.toList());
List<String> actor2 = actors2.stream().filter(actor -> actor.split(",")[0].startsWith("杨")).skip(1).collect(Collectors.toList());
List<Actor> actors = Stream.concat(actor1.stream(), actor2.stream()).map(actor -> {
Actor actor3 = new Actor();
String name = actor.split(",")[0];
Integer age = Integer.parseInt(actor.split(",")[1]);
actor3.setName(name);
actor3.setAge(age);
return actor3;
}).collect(Collectors.toList());
System.out.println(actors.toString());
}
static class Actor{
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Actor{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
}



