创建集合元素,完成以下需求,
- 把所有“张”开头的元素存储到新集合中
- 把“张”开头的元素,长度为3的元素存储到新集合中
- 遍历打印最终结果
package stream;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("张无忌");
list.add("张翠山");
list.add("张良");
list.add("王二麻子");
list.add("谢广坤");
list.add("张三丰");
ArrayList<String> list1 = new ArrayList<>();
list.forEach(s -> {
if (s.startsWith("张")) list1.add(s);
});
System.out.println(list1);
ArrayList<String> list2 = new ArrayList<>();
list1.forEach(s -> {
if (s.length() == 3) list2.add(s);
});
System.out.println(list2);
list.stream().filter(s -> s.length() == 3 && s.startsWith("张")).forEach(System.out::println);
}
}
- 创建一个
Stream流(流水线),并把数据放上去
| 获取方式 | 方法名 | 说明 |
|---|
| 单列集合 | default Stream<E> stream() | Collection中的默认方法 |
| 双列集合 | 无 | 无法使用 |
| 数组 | public static<T> Stream<T> stream(T... values) | Arrays工具类中的静态方法 |
| 一堆零散数据 | public static<T> Stream<T> of(T... values) | stream接口中的静态方法 |
package stream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.stream.Stream;
public class StreamDemo {
public static void main(String[] args) {
ArrayList<String> list3 = new ArrayList<>();
Collections.addAll(list3, "张无忌", "张翠山", "张良", "王二麻子", "谢广坤", "张三丰");
Stream<String> stream = list3.stream();
stream.forEach(System.out::println);
}
}
package stream;
import java.util.*;
public class StreamDemo2 {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("001", "张无忌");
map.put("002", "张翠山");
map.put("003", "张良");
map.put("004", "王二麻子");
map.put("005", "谢广坤");
map.put("006", "张三丰");
Stream<String> stream1 = map.keySet().stream();
stream1.forEach(System.out::println);
System.out.println("----------------------------------------------------------------------------------------");
Set<Map.Entry<String, String>> set = map.entrySet();
System.out.println(set);
Stream<Map.Entry<String, String>> stream2 = set.stream();
stream2.forEach(System.out::println);
}
}
package stream;
import java.util.*;
import java.util.stream.Stream;
public class StreamDemo3 {
public static void main(String[] args) {
String[] arr = {"张无忌", "张翠山", "张良", "王二麻子", "谢广坤", "张三丰"};
Arrays.stream(arr).forEach(System.out::println);
}
}
package stream;
import java.util.*;
import java.util.stream.Stream;
public class StreamDemo4 {
public void main(String[] args) {
Stream.of("张无忌", "张翠山", "张良", "王二麻子", "谢广坤", "张三丰").forEach(System.out::println);
}
}
注意
- stream流只能使用一次,使用后流就关闭了,再次使用会报错。
- 零散数据获取stream流时,可以传递整个数组,但只能传递引用数据类型的数组,如果传递基本数据类型,是会把整个数组当作一个元素,放到stream流中
| 名称 | 说明 |
|---|
stream<T> filter(Predicate<? super T> predicate) | 过滤数据 |
stream<T> distinct() | 去重,依赖(hashCode()和equals()) |
stream<T> limit(long maxSize) | 获取前几个元素 |
stream<T> skip(long n) | 跳过前n个元素 |
static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) | 合并两个流 |
stream<T> map(Function<? super T, ? extends R> mapper) | 将元素转换成其他形式或提取信息,接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。 |
注意
- 中间方法返回新的
Stream流,原来的stream流只能使用一次,建议使用链式编程 - 修改
stream流中的数据,不会影响原来集合或者数组中的数据 - 使用
concat合并两个流时尽量保持两个流的累心一致,否则输出会去两个类的父类类型
package stream;
import java.util.*;
import java.util.stream.Stream;
public class StreamDemo5 {
public static void main(String[] args) {
ArrayList<String> list4 = new ArrayList<>();
Collections.addAll(list4, "张无忌", "张翠山", "张良", "张良", "谢广坤", "张三丰");
list4.stream().filter(s -> s.startsWith("张")).forEach(System.out::println);
list4.stream().limit(3).forEach(System.out::println);
list4.stream().skip(3).forEach(System.out::println);
list4.stream().distinct().forEach(System.out::println);
System.out.println("----------------------------------------------------------------------------------------");
ArrayList<pople> list5 = new ArrayList<>();
Collections.addAll(list5, new pople("张无忌", 18), new pople("张三", 18), new pople("张三", 18), new pople("王五", 30));
list5.stream().distinct().forEach(s -> System.out.println(s.name));
System.out.println("----------------------------------------------------------------------------------------");
ArrayList<String> list6 = new ArrayList<>();
Collections.addAll(list6, "张无忌", "张翠山", "张良", "王二麻子", "谢广坤", "张三丰");
ArrayList<String> list7 = new ArrayList<>();
Collections.addAll(list7, "张无忌", "张翠山", "张良", "王二麻子", "谢广坤", "张三丰");
Stream<String> stream3 = Stream.concat(list6.stream(), list7.stream());
stream3.forEach(System.out::println);
System.out.println("----------------------------------------------------------------------------------------");
ArrayList<String> list8 = new ArrayList<>();
Collections.addAll(list8, "张无忌-10", "张翠山-20", "张良-30", "王二麻子-40", "谢广坤-50", "张三丰-60");
list8.stream().map(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
String[] split = s.split("-");
return parseInt(split[1]);
}
}).forEach(System.out::println);
list8.stream().map(s -> Integer.parseInt(s.split("-")[1])).forEach(System.out::println);
}
static class pople {
String name;
int age;
public pople(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
pople pople = (pople) o;
return age == pople.age;
}
@Override
public int hashCode() {
return Objects.hash(age);
}
}
}
| 名称 | 说明 |
|---|
void forEach(Consumer<? super T> action) | 遍历流中的元素 |
long count() | 统计流中元素个数 |
toArray() | 收集流中的数据,放到数组中 |
collect(Collector<? super T, A, R> collector) | 收集流中的数据放到集合中 |
package stream;
import java.util.*;
import java.util.stream.Stream;
public class StreamDemo6 {
public static void main(String[] args) {
list8.stream().forEach(System.out::println);
System.out.println(list8.stream().count());
Object[] arr2 = list8.stream().toArray();
System.out.println(Arrays.toString(arr2));
String[] arr3 = list8.stream().toArray(new IntFunction<String[]>() {
@Override
public String[] apply(int value) {
System.out.println("value = " + value);
return new String[value];
}
});
System.out.println(Arrays.toString(arr3));
String[] arr4 = list8.stream().toArray(s -> new String[s]);
System.out.println(Arrays.toString(arr4));
}
}
使用collect函数可以收集流中的数据,放到List、Set、Map等集合中。
package stream;
import java.util.*;
import java.util.stream.Stream;
public class StreamDemo7 {
public static void main(String[] args) {
ArrayList<String> list9 = new ArrayList<>();
Collections.addAll(list9, "张无忌-男-18", "张翠山-男-19", "张良-女-20", "王二麻子-男-21", "谢广坤-男-22", "张三丰-男-23");
List<String> list10 = list9.stream().filter(s -> s.split("-")[1].equals("男")).collect(Collectors.toList());
System.out.println(list10);
Set<String> setList = list9.stream().filter(s -> s.split("-")[1].equals("男")).collect(Collectors.toSet());
System.out.println(setList);
Map<String, String> stringMap = list9.stream().filter(s -> s.split("-")[1].equals("男")).collect(Collectors.toMap(s -> s.split("-")[0], s -> s.split("-")[2]));
System.out.println(stringMap);
}
}
是 java.util.stream 包中的一个工具类,专门用于在流( Stream )操作中执行可变归约(mutable reduction),例如将元素收集到集合(如 List 、 Set 、 Map )或汇总统计(如求和、平均值等)。
- Collectors 提供了一系列静态工厂方法,用于将流中的元素收集或汇总为以下形式:
- 集合(如 List 、 Set 、 Map )。
- 字符串(如拼接)。
- 数值统计(如求和、平均值、最大值等)。
- 分组和分区。
| 方法 | 说明 |
|---|
toList() | 收集为List集合 |
toSet() | 收集为Set集合 |
toCollection(Supplier) | 收集为Collection自定义集合 |
toMap(keyMapper, valueMapper) | 收集为Map集合,key是根据keyMapper函数来生成的,value是根据valueMapper函数来生成的 |
| 方法 | 说明 |
|---|
joining() | 拼接所有元素,默认用英文逗号分隔 |
joining(delimiter) | 拼接所有元素,指定分隔符 |
joining(prefix, delimiter, suffix) | 拼接所有元素,指定前缀、分隔符、后缀,拼接结果为字符串 |
| 方法 | 说明 |
|---|
summingInt(ToIntFunction) | 对 int 类型字段求和 |
summingLong(ToLongFunction) | 对 long 类型字段求和 |
summingDouble(ToDoubleFunction) | 对 double 类型字段求和 |
averagingInt(ToIntFunction) | 对int字段求平均值 |
averagingLong(ToLongFunction) | 对long字段求平均值 |
averagingDouble(ToDoubleFunction) | 对double字段求平均值 |
summarizingInt(ToIntFunction) | 对int字段求统计值(sum、min、max、average) |
| 方法 | 说明 |
|---|
groupingBy(classifier) | 按条件分组,返回 Map<K, List<T>> 。 |
partitioningBy(predicate) | 按布尔条件分区,返回 Map<Boolean, List<T>> 。 |
| 方法 | 说明 |
|---|
counting() | 计算元素数量。 |
reducing() | 自定义归约操作(类似 reduce )。 |
mapping(mapper, downstream) | 先映射再收集。 |
定义一个集合,并添加一些整数 过滤奇数只留下偶数,并把结果收集起来
package stream;
public class StreamDemo8 {
public static void main(String[] args) {
ArrayList<Integer> list11 = new ArrayList<>();
Collections.addAll(list11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> list12 = list11.stream().filter(s -> s % 2 == 0).toList();
System.out.println(list12);
}
}
创建一个ArrayList集合,并添加一些字符串,字符串前面是姓名后面是年龄 保留年龄大于24的人,并将结果收集到map集合中,姓名为键,年龄为值
package stream;
public class StreamDemo9 {
public static void main(String[] args) {
ArrayList<String> list13 = new ArrayList<>();
Collections.addAll(list13, "张无忌-18", "张翠山-19", "张良-20", "王二麻子-21", "谢广坤-22", "张三丰-23");
Map<String, Integer> map1 = list13.stream().map(s -> {
String[] split = s.split("-");
return new String[]{split[0], split[1]};
}).filter(s -> parseInt(s[1]) > 18).collect(Collectors.toMap(s -> s[0], s -> parseInt(s[1])));
System.out.println(map1);
}
}