一、不可变集合
含义

应用场景

格式:

List.of()参数是个可变参数,可以放可变个数的参数。
一旦创建,不能删除、添加,不能修改。
Set:

Map的不可变集合,of(),键值对数量不能超过10,代码如下:

创建Map的不可变集合,长度超过10个键值对,方法是将键值对打包成Map.Entry的类型,传递超过10个元素的数组就行了

最后会报错,不能添加
简化代码:

最后会报错,因为不可变集合不能添加元素。
最后用copyof(hashmap类型的对象)即可,因为copyof底层原理就是上面那一行 的简化代码。
心得:可变参数是一个数组,所以实参传递一个数组就可以了。
键值对类型是 Map.Entry
创建一个键值对类型的数组:Map.Entry [] arr=new Map.Entry[0];//长度为0
把一个集合类型转变为数组类型:集合名.toArray(参数为某个类型的数组对象)
自己写代码:
java
package com.不可变集合;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class 不可变集合 {
public static void main(String[] args) {
List<Integer> list=List.of(1,2,7,8,9);
//list是个不可变集合
//list.add(2);//会报错
Set<String> set=Set.of("aaa","bbb","ccc");
//set.remove("bbb");//set是一个不可变集合,会报错
Map<String,String> map=Map.of("aaa","123","bbb","222");
//map.put("bbb","456");
HashMap<String,Integer> hm=new HashMap<>();
hm.put("aaa",111);
hm.put("bbb",222);
hm.put("ccc",333);
Map<String,Integer> map1=Map.copyOf(hm);
//map1是个不可变集合,所以......
map1.remove("aaa");
}
}
总结

二、stream流
2.1如何变成stream流



1、单列集合
java
package com.Stream;
import java.util.ArrayList;
import java.util.Collections;
public class Streamdemo1 {
public static void main(String[] args) {
//单列集合,用collection接口自带的stream方法获取流水线,
// 并把集合中的数据放到流水线上
ArrayList<Integer> list=new ArrayList<>();
Collections.addAll(list,1,2,3,5,7,90);
list.stream().forEach(s-> System.out.println(s));
}
}
在list/set上直接调用stream方法
2、双列集合
要先把map调用keyset和entryset方法变成set集合,之后才能用collection接口的stream方法
entryset()方法得到的集合数据类型是Map.entry类型,打印的结果是:
java
[aaa=1, ccc=3, bbb=2, ddd=4]
java
package com.Stream;
import java.util.HashMap;
public class Streamdemo2 {
public static void main(String[] args) {
HashMap<String,Integer> map=new HashMap<>();
map.put("aaa",1);
map.put("bbb",2);
map.put("ccc",3);
map.put("ddd",4);
map.entrySet().stream().forEach(s-> System.out.println(s));
map.keySet().stream().forEach(s-> System.out.println(s));
}
}
3、数组array
用arrays.stream()方法
java
package com.Stream;
import java.util.Arrays;
public class Streamdemo3 {
public static void main(String[] args) {
//对数组stream
int[] arr={1,2,6,8,9};
Arrays.stream(arr).forEach(s-> System.out.println(s));
}
}
4、零散数据
用stream接口的of()方法
java
package com.Stream;
import java.util.stream.Stream;
public class Streamdemo4 {
public static void main(String[] args) {
Stream.of(1,2,3,4).forEach(s-> System.out.println(s));
int []arr={1,2,3};
Stream.of(arr).forEach(s-> System.out.println(s));//[I@682a0b20
String []arr2={"aaa","dd","c"};
Stream.of(arr2).forEach(s-> System.out.println(s));//aaa
//dd//c
}
}
用stream接口的of方法时,参数是可变参数,可以传递零散数据,也可以传递数组,但是数组必须得是引用类型,不能是基本数据类型。
2.2stream流的中间方法
**将字符串变成int类型:**Integer.parseInt()方法,参数填写字符串,返回值是int类型。

1、filter()过滤

filter参数里面的匿名内部类return后面是boolean类型,只留下符合的元素,true留下,false过滤掉
注意1:代码示例:

java
ArrayList<String> list=new ArrayList<>();
Collections.addAll(list,"张无极","周芷若","张基尼","赵敏","王朔","张忙","李帅","谢想");
list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.startsWith("张");
}
}).forEach(s-> System.out.println(s));
System.out.println("=====================");
list.stream().filter(s->s.startsWith("张")).forEach(s-> System.out.println(s));
System.out.println("=========================");
list.stream()
.filter(s->s.startsWith("张"))
.filter(s->s.length()==3)
.forEach(s-> System.out.println(s));
2、limit()获取前几个元素
java
list.stream() //获取前三个元素
.limit(3)
.forEach(s-> System.out.println(s));
3、skip()跳过前几个元素
java
list.stream()//"张基尼","赵敏","王朔"
.skip(2)
.limit(3)
.forEach(s-> System.out.println(s));
4、distinct()元素去重,依赖hashCode和equals方法
自己定义的引用数据类型一定要重写hashcode和equals方法
java
ArrayList<String> list2=new ArrayList<>();
Collections.addAll(list2,"张无极","张无极","张无极","张无极","周芷若","张基尼","赵敏","王朔","张忙","李帅","谢想");
System.out.println("+++++++++++++++");
list2.stream().forEach(s-> System.out.println(s));
System.out.println("========================");
list2.stream()//去重
.distinct()
.forEach(s-> System.out.println(s));
输出:
java
+++++++++++++++
张无极
张无极
张无极
张无极
周芷若
张基尼
赵敏
王朔
张忙
李帅
谢想
========================
张无极
周芷若
张基尼
赵敏
王朔
张忙
李帅
谢想
5、concat()合并a流和b流为一个流,新流为ab的父类类型
java
ArrayList<String> list3=new ArrayList<>();
Collections.addAll(list3,"张无极","臭蛋","周芷若","张基尼","赵敏","王朔","张忙","李帅","谢想");
ArrayList<String> list4=new ArrayList<>();
Collections.addAll(list4,"张无极","张有极","张很极","张少极","周芷若","张基尼","赵敏","王朔","张忙","李帅","谢想");
System.out.println("----------------------------");
Stream.concat(list3.stream(),list4.stream()).forEach(s-> System.out.println(s));
输出
java
----------------------------
张无极
臭蛋
周芷若
张基尼
赵敏
王朔
张忙
李帅
谢想
张无极
张有极
张很极
张少极
周芷若
张基尼
赵敏
王朔
张忙
李帅
谢想
6、map()转换流中的数据类型
string字符串类型把每个元素中的数字,抽取出来,再转换成整数类型。
java
System.out.println("---------------------");
ArrayList<String> list5=new ArrayList<>();
Collections.addAll(list5,"张无极-15","臭蛋-16","周芷若-25","张基尼-100","赵敏-52","王朔-29","张忙-57","李帅-22","谢想-56");
list5.stream().map(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
String []arr=s.split("-");//得到的是一个数组
String age=arr[1];
int i = Integer.parseInt(age);
return i;
}
}).forEach(s-> System.out.println(s));
//简化
list5.stream()
.map(s->Integer.parseInt(s.split("-")[1]))
.forEach(s-> System.out.println(s));
输出
java
---------------------
15
16
25
100
52
29
57
22
56
15
16
25
100
52
29
57
22
56
2.3stream流的终结方法

1、forEach()

foreach返回值是void,而不是stream类型,所以是终结方法。
2、count()

返回值是long,整数类型,是返回流中的元素个数。
3、toArray()方法
把处理后的stream流存储到数组中保存起来,以便后续使用
有两种,一种无参,一种有参
java
package com.Stream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.IntFunction;
public class Last_method {
public static void main(String[] args) {
ArrayList<String> list=new ArrayList<>();
Collections.addAll(list,"张无极","周芷若","张基尼","赵敏","王朔","张忙","李帅","谢想");
long count = list.stream().count();
System.out.println(count);
System.out.println("无参");
//无参
Object[] s = list.stream().toArray();//s是流中的元素组成的数组
System.out.println(Arrays.toString(s));
System.out.println("有参");
//有参
String[] array = list.stream().toArray(new IntFunction<String[]>() {
@Override //value是流中元素的个数
public String[] apply(int value) {
return new String[value];
}
});
System.out.println(Arrays.toString(array));
}
}
输出
java
8
无参
[张无极, 周芷若, 张基尼, 赵敏, 王朔, 张忙, 李帅, 谢想]
有参
[张无极, 周芷若, 张基尼, 赵敏, 王朔, 张忙, 李帅, 谢想]
lambda表达式
java
System.out.println(Arrays.toString(list.stream().toArray(value -> new String[value])));
4、collect()方法
有toList 、toSet 、toMap三个方法
java
package com.Stream;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
public class Last_method_2 {
public static void main(String[] args) {
ArrayList<String> list=new ArrayList<>();
Collections.addAll(list,"张无忌-男-21","李晨-男-41","张良-男-28","丹淡-女-21","帅比-男-28");
//筛选出男生并收集到list集合中
List<String> collect = list.stream()
.filter(s->"男".equals(s.split("-")[1]))
.collect(Collectors.toList()); //toList方法是创建一个ArrayList集合
System.out.println(collect);
//筛选出男生并收集到set集合中
Set<String> set = list.stream()
.filter(s->"男".equals(s.split("-")[1]))
.collect(Collectors.toSet());//toset方法是创建一个hashset集合会自动去重
System.out.println(set);
//筛选出男生并收集到map集合当中,键是名字,值是年龄
Map<String, Integer> map = list.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);//map集合千万不能用键重复的集合。会报错
}
}
输出
java
[张无忌-男-21, 李晨-男-41, 张良-男-28, 帅比-男-28]
[李晨-男-41, 张无忌-男-21, 张良-男-28, 帅比-男-28]
{张良=28, 帅比=28, 李晨=41, 张无忌=21}
lambda表达式
java
Map<String, Integer> map2 = list.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toMap(s -> s.split("-")[0], s -> Integer.parseInt(s.split("-")[2])));
System.out.println(map2);
2.4总结

2.5代码练习题

java
package com.Stream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public class test1 {
public static void main(String[] args) {
ArrayList<Integer> list=new ArrayList<>();
Collections.addAll(list,1,2,3,4,5,6,7,8,9,10);
List<Integer> collect = list.stream()
.filter(s -> s % 2 == 0)
.collect(Collectors.toList());
System.out.println(collect);
}
}

java
package com.Stream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.util.stream.Collectors;
public class test2 {
public static void main(String[] args) {
ArrayList<String> list=new ArrayList<>();
Collections.addAll(list,"zhangsan,23","lisi,24","wangwu,25");
Map<String, Integer> map = list.stream()
.filter(s -> Integer.parseInt(s.split(",")[1]) >= 24)
.collect(Collectors.toMap(s -> s.split(",")[0], s -> Integer.parseInt(s.split(",")[1])));
System.out.println(map);
}
}

java
package com.Stream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class test3 {
public static void main(String[] args) {
ArrayList<String> manList=new ArrayList<>();
ArrayList<String> WomanList=new ArrayList<>();
Collections.addAll(manList,"李晨,23","苏无名,25","陆凌枫,29","潇洒哥,24","刘晓雷,33","范凯,58");
Collections.addAll(WomanList,"杨阳晨,23","杨新宇,25","杨晓岚,26","丹丹,24","欣欣,37","佳佳,18");
Stream<String> stream1 = manList.stream()
.filter(s -> s.split(",")[0].length() >= 3)
.limit(2);
Stream<String> stream2 = WomanList.stream()
.filter(s -> s.startsWith("杨"))
.skip(1);
//类型转换用map方法,封装成actor类型
/*List<actor> collect = Stream.concat(stream1, stream2).map(new Function<String, actor>() {
@Override
public actor apply(String s) {
String name = s.split(",")[0];
int age = Integer.parseInt(s.split(",")[1]);
return new actor(name, age);
}
}).collect(Collectors.toList());*/
//System.out.println(collect);
List<actor> collect1 = Stream.concat(stream1, stream2).map(s -> new actor(s.split(",")[0], Integer.parseInt(s.split(",")[1])))
.collect(Collectors.toList());
System.out.println(collect1);
}
}
两个流concat变成一个流,只能用一次,第二次contat就会报错。