stream流与IO流没有任何关系,stream流类似车间的生产线,对数据进行加工,不存储数据
public class StreamIntro {
public static void main(String[] args) {
// 方式一: 通过Collection接口的stream()方法获取流
List<String> arrayList = new ArrayList<>();
Stream<String> stream = arrayList.stream();
Set<String> set = new HashSet<>();
Stream<String> stream1 = set.stream();
Map<String, String> map = new HashMap<>();
Stream<String> stream2 = map.keySet().stream();
Stream<String> stream3 = map.values().stream();
Stream<Map.Entry<String, String>> stream4 = map.entrySet().stream();
// 方式二: 通过Stream接口中的静态方法of获取流
Stream<String> stream5 = Stream.of("zdy", "zyz", "cyx", "mcs");
String[] strs = {"zdy", "zyz", "cyx", "mcs"};
Stream<String> stream6 = Stream.of(strs);
}
}
stream常用方法分为两类
终结方法:返回值不是Stream流类型的方法,不再支持链式调用,例如:count、forEach
非终结方法:返回值是Stream流类型的方法,支持链式调用,例如:filter、limit、map、skip
遍历集合中的每一个元素
public class StreamIntro {
public static void main(String[] args) {
Stream<String> stream = Stream.of("zdy", "zyz", "cyx", "mcs");
stream.forEach(System.out::println); // 打印 "zdy" "zyz" "cyx" "mcs"
}
}
计算集合的长度
public class StreamIntro {
public static void main(String[] args) {
Stream<String> stream = Stream.of("zdy", "zyz", "cyx", "mcs");
long count = stream.count();
System.out.println(count); // 打印 4
}
}
自定义编写过滤规则,通过规则的数据留下,支持链式调用
public class StreamIntro {
public static void main(String[] args) {
Stream<String> stream = Stream.of("zdy", "zyz", "cyx", "mcs");
stream.filter(s -> s.contains("z")) // 包含"z"的留下
.filter(s -> s.contains("y")) // 包含"y"的留下
.forEach(System.out::println); // 打印 "zdy" "zyz"
}
}
取集合中的前n个数据
public class StreamIntro {
public static void main(String[] args) {
Stream<String> stream = Stream.of("zdy", "zyz", "cyx", "mcs");
stream.limit(2).forEach(System.out::println); // 打印 "zdy" "zyz"
}
}
从第几条数据开始取
public class StreamIntro {
public static void main(String[] args) {
Stream<String> stream = Stream.of("zdy", "zyz", "cyx", "mcs");
stream.skip(2).forEach(System.out::println); // 打印 "cyx" "mcs"
}
}
将一种类型的流转换为另一种类型的流
public class StreamIntro {
public static void main(String[] args) {
// 通过map 将Stream类型转换为Stream类型
Stream<String> stream = Stream.of("1", "2", "3", "4");
Stream<Integer> stream1 = stream.map(Integer::parseInt);
}
}
排序方法,支持自定义比较器
public class StreamIntro {
public static void main(String[] args) {
Stream<Integer> stream = Stream.of(5, 2, 7, 4);
stream.sorted((num1, num2) -> num1 - num2).forEach(System.out::println); // 打印 2 4 5 7
}
}
去重方法
public class StreamIntro {
public static void main(String[] args) {
Stream<String> stream = Stream.of("zdy", "zdy", "zyz", "zyz", "cyx", "mcs");
stream.distinct().forEach(System.out::println); // 打印 "zdy" "zyz" "cyx" "mcs"
}
}
匹配方法,细分为三个,allMatch所有数据都满足条件,anyMatch任意一条数据满足条件,noneMatch没有数据满足条件,都返回boolean类型
public class StreamIntro {
public static void main(String[] args) {
Stream<Integer> stream = Stream.of(5, 2, 7, 4);
boolean match = stream.allMatch(num -> num > 4); // 所有数据都>4吗
System.out.println(match); // 打印 "false"
Stream<Integer> stream2 = Stream.of(5, 2, 7, 4);
boolean anyMatch = stream2.anyMatch(num -> num > 4); // 有数据>4吗
System.out.println(anyMatch); // 打印 "true"
Stream<Integer> stream3 = Stream.of(5, 2, 7, 4);
boolean noneMatch = stream3.noneMatch(num -> num == 3); // 没有数据=3吗
System.out.println(noneMatch); // 打印 "true"
}
}
获取最大值,支持自定义比较器,通过比较器也可以实现min的功能
public class StreamIntro {
public static void main(String[] args) {
Stream<Integer> stream = Stream.of(5, 2, 7, 4);
Optional<Integer> max = stream.max((num1, num2) -> num1 - num2);
System.out.println(max.get()); // 打印 "7"
}
}
获取最小值,支持自定义比较器,通过比较器也可以实现max的功能
public class StreamIntro {
public static void main(String[] args) {
Stream<Integer> stream = Stream.of(5, 2, 7, 4);
Optional<Integer> min = stream.min((num1, num2) -> num1 - num2);
System.out.println(min.get()); // 打印 "2"
}
}
将所有的数据归纳为一个数据
public class StreamIntro {
public static void main(String[] args) {
Stream<Integer> stream = Stream.of(5, 2, 7, 4);
// 参数1 默认值 参数2 数据处理方式 以下代码可以理解为 reduce=默认值-5-2-7-4
Integer reduce = stream.reduce(0, (num1, num2) -> num1 - num2);
System.out.println(reduce); // -18
}
}
合并两个流
public class StreamIntro {
public static void main(String[] args) {
Stream<String> stream1 = Stream.of("zdy", "zyz", "cyx", "mcs");
Stream<Integer> stream2 = Stream.of(5, 2, 7, 4);
Stream<? extends Serializable> stream = Stream.concat(stream1, stream2);
stream.forEach(System.out::println); // 打印 "zdy" "zyz" "cyx" "mcs" 5 2 7 4
}
}
public class StreamIntro {
public static void main(String[] args) {
Stream<String> stream1 = Stream.of("zdy", "zyz", "cyx", "mcs");
// 保存到Set中
Set<String> collect = stream1.collect(Collectors.toSet());
// 保存到List中
List<String> collect1 = stream1.collect(Collectors.toList());
// 保存到ArrayList
ArrayList<String> collect2 = stream1.collect(Collectors.toCollection(ArrayList::new));
// 保存到ArraySet
HashSet<String> collect3 = stream1.collect(Collectors.toCollection(HashSet::new));
}
}
public class StreamIntro {
public static void main(String[] args) {
Stream<String> stream1 = Stream.of("zdy", "zyz", "cyx", "mcs");
// 保存成数组
String[] strings = stream1.toArray(String[]::new);
}
}
对流中数据进行聚合计算
public class StreamIntro {
public static void main(String[] args) {
Stream<String> stream1 = Stream.of("zdy", "zyz", "cyx", "mcs");
Stream<Person> stream = Stream.of(new Person("zdy", 23),
new Person("zyz", 24),
new Person("cyx", 25),
new Person("mcs", 26));
// maxBy 获取年龄最大值 minBy 获取最小值
Optional<Person> collect = stream.collect(Collectors.maxBy((p1, p2) -> p1.getAge() - p2.getAge()));
System.out.println(collect.get());
Stream<Person> stream2 = Stream.of(new Person("zdy", 23),
new Person("zyz", 24),
new Person("cyx", 25),
new Person("mcs", 26));
// summingInt 求年龄总和
IntSummaryStatistics collect1 = stream2.collect(Collectors.summarizingInt(Person::getAge));
// 年龄总和
System.out.println(collect1.getSum());
// 年龄平均值
System.out.println(collect1.getAverage());
// 统计数量
System.out.println(collect1.getCount());
}
}
对流中数据进行分组 多级分组
public class StreamIntro {
public static void main(String[] args) {
Stream<Person> stream2 = Stream.of(new Person("zdy", 23),
new Person("zyz", 24),
new Person("cyx", 23),
new Person("mcs", 24));
// 通过age进行分组 23一组 24一组
Map<Integer, List<Person>> collect = stream2.collect(Collectors.groupingBy(Person::getAge));
collect.forEach((k, v) -> {
System.out.println(k + " " + v);
// 打印
// 23 [Person(name=zdy, age=23), Person(name=cyx, age=23)]
// 24 [Person(name=zyz, age=24), Person(name=mcs, age=24)]
});
Stream<Person> stream3 = Stream.of(new Person("zdy", 21),
new Person("zyz", 22),
new Person("cyx", 25),
new Person("mcs", 24));
// 年龄>23分一组 <23分一组
Map<String, List<Person>> collect1 = stream3.collect(Collectors.groupingBy((person) -> {
if (person.getAge() > 23) {
return "高龄";
} else {
return "低龄";
}
}));
collect1.forEach((k, v) -> {
System.out.println(k + " " + v);
// 打印
// 低龄 [Person(name=zdy, age=21), Person(name=zyz, age=22)]
// 高龄 [Person(name=cyx, age=25), Person(name=mcs, age=24)]
});
Stream<Person> stream4 = Stream.of(new Person("zdy", 21),
new Person("zyz", 22),
new Person("cyx", 21),
new Person("mcs", 22));
// 多级分组 先根据年龄分组 再根据名字中是否含有"z"分组
Map<Integer, Map<String, List<Person>>> collect2 = stream4.collect(Collectors.groupingBy(Person::getAge, Collectors.groupingBy((person) -> {
if (person.getName().contains("z"))
return "含有";
else
return "不含有";
})));
collect2.forEach((k, v) -> {
System.out.println(k);
v.forEach((key, value) -> {
System.out.println(" " + key + " " + value);
// 打印
// 21
// 不含有 [Person(name=cyx, age=21)]
// 含有 [Person(name=zdy, age=21)]
// 22
// 不含有 [Person(name=mcs, age=22)]
// 含有 [Person(name=zyz, age=22)]
});
});
}
}
对流中数据进行分区,true一区,false一区
public class StreamIntro {
public static void main(String[] args) {
Stream<Person> stream2 = Stream.of(new Person("zdy", 21),
new Person("zyz", 22),
new Person("cyx", 25),
new Person("mcs", 24));
// 年龄>23分一区 <23分一区
Map<Boolean, List<Person>> collect = stream2.collect(Collectors.partitioningBy(p -> {
return p.getAge() > 23;
}));
collect.forEach((k, v) -> {
System.out.println(k + " " + v);
// 打印
// false [Person(name=zdy, age=21), Person(name=zyz, age=22)]
// true [Person(name=cyx, age=25), Person(name=mcs, age=24)]
});
}
}
根据指定的字符串,将所有元素连接成一个字符串
public class StreamIntro {
public static void main(String[] args) {
Stream<Person> stream1 = Stream.of(new Person("zdy", 21),
new Person("zyz", 22),
new Person("cyx", 25),
new Person("mcs", 24));
// 根据一个字符进行拼接
String collect = stream1.map(Person::getName).collect(Collectors.joining("_"));
System.out.println(collect);
// 打印
// zdy_zyz_cyx_mcs
Stream<Person> stream2 = Stream.of(new Person("zdy", 21),
new Person("zyz", 22),
new Person("cyx", 25),
new Person("mcs", 24));
// 根据三个字符进行拼接 三个字符串分别为分隔符、前缀、后缀
String collect1 = stream2.map(Person::getName).collect(Collectors.joining("_", "@", "^"));
System.out.println(collect1);
// 打印
// @zdy_zyz_cyx_mcs^
}
}
public class StreamIntro {
public static void main(String[] args) {
// 方式一 直接获取并行流
ArrayList<Object> list = new ArrayList<>();
Stream<Object> stream = list.parallelStream();
// 方式二 将串行流转换为并行流
Stream<Integer> parallel = Stream.of(1, 3, 4, 5, 6, 7, 3, 2).parallel();
long count = parallel.filter(num -> {
System.out.println(Thread.currentThread() + " " + num);
// 打印 由此可见是多个线程一起执行
// Thread[main,5,main] 7
// Thread[ForkJoinPool.commonPool-worker-23,5,main] 3
// Thread[main,5,main] 6
// Thread[ForkJoinPool.commonPool-worker-5,5,main] 2
return num > 3;
}).count();
}
}