语法补充:
name.startwith(“xxx”) -> 以xxx开头的字符串有哪些
Stream流的思想
Stream流的作用:结合Lambda表达式,简化集合、数组的操作
- 过滤操作
- 中间方法:过滤,转换
- 方法调用完后还可以调用其他方法
- 终结方法:输出打印
- 方法调用后不能再调用其他方法
- 中间方法:过滤,转换
- 长度筛选
- 输出
单列集合获取Stream流
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"aa","bb");
//第一种方式:
Stream<String> str = list.stream();
str.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
//第二种方式(常用):
list.stream().forEach(s -> System.out.println(s));
}
双列集合获取Stream流
HashMap<Integer, String> hm = new HashMap<>(Map.of(1,"hello",
3,"world",5,"nihao"));
//第一种方式:让双列集合变换为entryset
Set<Map.Entry<Integer, String>> entries = hm.entrySet();
entries.stream().forEach(System.out::println);
//第二种方式:让双列集合变换为KeySet
Set<Integer> key = hm.keySet();
TreeSet<Integer> ts = new TreeSet<>();
key.stream().forEach(s -> ts.add(s));
System.out.println(ts);
ts.stream().forEach(s -> System.out.println(s + hm.get(s)));
数组获取Stream流
int[] arr = {1,2,3,4};
Arrays.stream(arr).forEach(s -> System.out.println(s));
零散数据获取Stream流
Stream.of(1,2,3,4,"a").forEach(s -> System.out.println(s));
of的细节:
- 方法的形参是一个可变参数,可以传递引用数据类型数组,如果传递的是基本数据类型那么会把数组当成一个元素,输出的是地址值
Stream中间方法
- filter
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list,"张无忌","周芷若","张蔷","照明","张三丰","王二麻子");
//过滤的规则
list.stream().filter(new Predicate<String>() {
@Override
public boolean test(String s) {
//返回值True 留下 False丢弃
return s.startsWith("张");
}
}).forEach(s -> System.out.println(s));
list.stream() //使用这种写法更优
.filter(s -> s.startsWith("张"))
.filter(s -> s.length() == 3)
.forEach(s -> System.out.println(s));
- limit:获取前3个元素
list.stream().limit(3).forEach(s -> System.out.println(s));
输出:
张无忌
周芷若
张蔷
- skip:跳过前n个元素
list.stream().skip(4).forEach(s -> System.out.println(s));
输出:
张三丰
王二麻子
- distinct:去重
list.stream()
.distinct()
.forEach(s -> System.out.println(s));
- concat:将两个相同类型的Stream拼接在一起
ArrayList<String> list1 = new ArrayList<>();
Collections.addAll(list1,"单子","于子");
Stream.concat(list.stream(),list1.stream())
.forEach(s -> System.out.println(s));
}
- map:转换流中的数据类型
ArrayList<String> list2 = new ArrayList<>();
Collections.addAll(list2,"斩无极-11","huangwei-299","理清-22");
//第一种方法
list2.stream()
.map(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
String[] age = s.split("-");
int i = Integer.parseInt(age[1]);
return i;
}
}).forEach(s -> System.out.println(s));
//第二种方法
list2.stream()
.map(s -> Integer.parseInt(s.split("-")[1]))
.forEach(s -> System.out.println(s));
注意事项:
- 中间方法返回的是Stream流,原来的Stream只能使用一次建议使用链式编程
- 修改Stream流中的数据不会影响原来集合或者数组的数据
Stream终结方法
- foreach
list.stream().forEach(new Consumer<String>() {
@Override
//s 表示 流里面的每一个数据
public void accept(String s) {
System.out.println(s);
}
});
//Lambda表达式
list.stream()
.forEach(s -> System.out.println(s));
- count
//打印流里面的数据的数量
System.out.println(list.stream().count());
- toArray
//集合->流->数组
Object[] array = list.stream().toArray();
System.out.println(Arrays.toString(array));
//第二种
String[] array3 = list.stream()
.toArray(value -> new String[value]);
- collect
//转换为map
Map<String, Integer> mp = list.stream()
.filter(s -> "男".equals(s.split("-")[1]))
//两个形参 第一个形参表示流中的数据,第二个形参表示map中键还是值?
//tomap->第一个形参表示键的生成规则,第二个形参表示值的生成规则
.collect(Collectors.toMap(new Function<String, String>() {
@Override
public String apply(String s) {
//生成键
String s1 = s.split("-")[0];
return s1;
}
},
new Function<String, Integer>() {
@Override
//生成值
public Integer apply(String s) {
int s2 = Integer.parseInt(s.split("-")[2]);
return s2;
}
}));
Set<Map.Entry<String, Integer>> entries = mp.entrySet();
System.out.println(entries);
//第二种方法
Map<String, String> mp1 = list.stream()
.filter(s -> "男".equals(s.split("-")[1]))
.collect(Collectors.toMap(
s -> s.split("-")[0],
s -> s.split("-")[2]
));
System.out.println(mp1);
转换为Set
Set<String> list1 = list.stream()
.filter(new Predicate<String>() {
@Override
public boolean test(String s) {
String ismale = s.split("-")[1];
if (ismale.equals("男"))
return true;
else return false; }
}).collect(Collectors.toSet());
总结: