Stream 流对象的创建与各方法
目录
2.1 对于 Collection 系列集合创建 Stream 流对象的方式
2.2 对于 Map 系列集合创建 Stream 流对象的方式
4.3 Stream 流的 max() 或者 min() 终结方法
1.0 Stream 流的说明
Stream(流)是一种数据处理的概念,它可以用来处理集合、数组或输入/输出等数据源的元素序列。流可以看作是一个从源到目标的元素序列,可以通过一系列连续的操作对其进行处理。流的操作可以分为两种类型:中间操作和终端操作。中间操作是对流进行处理并返回一个新的流,而终端操作是对流进行最终的处理并返回一个结果或副作用。
2.0 Stream 流对象的创建
主要以数组、集合来创建 Stream 流对象。
2.1 对于 Collection 系列集合创建 Stream 流对象的方式
直接用集合对象.stream() 实例方法创建 Stream 流对象。
以代码的形式来具体介绍:
// List 集合系列来创建 Stream 流对象
List<String> list = new ArrayList<>();
Collections.addAll(list,"张三","李四","王五","张麻子");
Stream<String> stream = list.stream();
// Set 集合系列来创建 Stream 流对象
Set<String> set = new HashSet<>();
Collections.addAll(set,"张三","李四","王五","张麻子");
Stream<String> stream1 = set.stream();
2.2 对于 Map 系列集合创建 Stream 流对象的方式
具体来介绍两种方式:第一种方法;把键值对“封装”成一个整体。第二种方法;分别把集合中的键和值全部获取出来,单独放在各个集合中。
以代码的形式来具体介绍:
// Map 集合系列来创建 Stream 流对象
Map<String,Integer> m = new HashMap<>();
m.put("张三",19);
m.put("李四",28);
m.put("王五",33);
m.put("张麻子",22);
//第一种方法:把键值对“封装”成一个整体
Set<Map.Entry<String,Integer>> entries = m.entrySet();
Stream<Map.Entry<String,Integer>> stream2 = entries.stream();
//第二种方法:分别把集合中的键和值全部获取出来,单独放在系列集合中
Set<String> k = m.keySet();
Collection<Integer> v = m.values();
Stream<String> stream3 = k.stream();
Stream<Integer> stream4 = v.stream();
2.3 对于数组创建 Stream 流对象的方式
具体来介绍有两种方式来创建对象:第一种方法;用 Arrays.stream() 方法来创建。第二种方法;用 Stream.of() 方法来创建。
以代码的形式来具体介绍:
// 用数组来创建 Stream 流对象
String[] strings = new String[]{"张三","李四","王五","张麻子"};
//第一种方法:用 Arrays.stream() 方法来创建
Stream<String> stream5 = Arrays.stream(strings);
//第二种方法:用 Stream.of() 方法来创建
Stream<String> stream6 = Stream.of(strings);
3.0 Stream 流的中间方法
Stream 流的中间方法主要用于对流中的元素进行处理,返回一个新的流对象。这些中间方法可以组合使用,形成流水线式的处理流程,方便进行复杂的数据处理操作。
3.1 Stream 流的 filter() 中间方法
用于对流中的数据进行过滤。
通过具体代码实现:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class StreamIntermediateMethod {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Collections.addAll(list,"张三","李四","王五","张麻子");
//对一下代码解读:首先用 stream() 得到了该集合的流,
//然后用 filter() 用于对流中的数据进行过滤,也可以理解成筛选字符串中带有“张”的,返回新流,
//该新流中都是含“张”的字符串,接着把流中的数据进行用 forEach() 方法进行遍历。
/*list.stream().filter(s -> s.contains("张")).forEach(s-> System.out.println(s));*/
//对以上代码稍微简化,如以下:
list.stream().filter(s -> s.contains("张")).forEach(System.out::println);
}
}
运行结果如下:
3.2 Stream 流的 sorted() 中间方法
按照指定规则排序。
通过具体代码实现:
import java.util.ArrayList;
import java.util.List;
public class StreamIntermediateMethod {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("张三",19));
list.add(new Student("李四",22));
list.add(new Student("王五",17));
list.add(new Student("张麻子",33));
//解读以下代码:首先先利用 stream() 方法来获取该集合的流,然后用 sorted() 方法,由于是自定义类型的对象,
//默认的 sorted() 方法是搞不定,所以需要重写方法,因此可以接入这个匿名内部类来重写内部的具体方法,
//排完序之后会得到一个新的流,然后经过 forEach 方法来遍历该流中的数据。
list.stream().sorted((o1, o2)-> o1.getAge() - o2.getAge()).forEach(s-> System.out.println(s));
//以上代码话可以继续简化,效果是一样的
System.out.println("--------------------------------------------------------------------");
list.stream().sorted((o1, o2)-> o1.getAge() - o2.getAge()).forEach(System.out::println);
}
}
运行结果如下:
3.3 Stream 流的 limit(x) 中间方法
获取前面 x 个元素。
通过具体代码实现:
import java.util.ArrayList;
import java.util.List;
public class StreamIntermediateMethod {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("张三",19));
list.add(new Student("李四",22));
list.add(new Student("王五",17));
list.add(new Student("张麻子",33));
//对一下代码进行解读:先获取该集合的流,然后用 limit(2) 中间方法,获取前面2个元素,
//返回新流,接着对新流进行遍历输出元素
list.stream().limit(2).forEach(System.out::println);
}
}
运行结果如下:
3.4 Stream 流的 skip(x) 中间方法
跳过前面 x 个元素。
通过具体代码实现:
import java.util.ArrayList;
import java.util.List;
public class StreamIntermediateMethod {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("张三",19));
list.add(new Student("李四",22));
list.add(new Student("王五",17));
list.add(new Student("张麻子",33));
//对一下代码进行解读:先得到该集合的流,然后用 skip(2) 中间方法,跳过前面2个元素,
//得到的新流中包含后面两个元素,然后就进行遍历了。
list.stream().skip(2).forEach(System.out::println);
}
}
运行结果如下:
3.5 Stream 流的 map() 中间方法
对元素进行加工,并返回对应的新流。(映射)
通过代码具体实现:
import java.util.ArrayList;
import java.util.List;
public class StreamIntermediateMethod {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("张三",19));
list.add(new Student("李四",22));
list.add(new Student("王五",17));
list.add(new Student("张麻子",33));
//解读以下代码: 先得到该集合的流,然后调用 map() 中间方法,
//将对应的元素进行加工,简单的来说就是,将原先的元素加工成自己想要的形式,
//以下就是将学生类对象加工成字符串,["张三",19] -> "张三",每一个元素都是一一对应、映射的。
list.stream().map(s->s.getName()).forEach(System.out::println);
}
}
运行结果如下:
3.6 Stream 流的 distinct() 中间方法
去除流中重复的元素。但是对于自定义类型的元素,默认的 distinct() 方法是不能完成去除重复的元素。希望内容一样就认为重复,这就需要重写 hashCode() 与 equals() 方法。
通过代码具体实现:
import java.util.ArrayList;
import java.util.List;
public class StreamIntermediateMethod {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("张三",19));
list.add(new Student("李四",22));
list.add(new Student("王五",17));
list.add(new Student("张麻子",33));
list.add(new Student("张三",19));
//解读以下代码: 先获取该集合中的流,然后调用 distinct() 方法,但是该流中的元素是自定义,
//所以希望内容一样就认为重复,这就需要重写 hashCode() 与 equals() 方法。
//去重后,返回一个新流。
list.stream().distinct().forEach(System.out::println);
}
}
运行结果如下:
3.7 Stream 流的 concat() 中间方法
合并 a 和 b 两个流为一个流。
通过代码具体实现:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class StreamIntermediateMethod {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("张三",19));
list.add(new Student("李四",22));
list.add(new Student("王五",17));
list.add(new Student("张麻子",33));
List<Student> list1 = new ArrayList<>();
list1.add(new Student("李麻子",23));
Stream<Student> stream = Stream.concat(list.stream(),list1.stream());
stream.forEach(System.out::println);
}
}
运行结果如下:
4.0 Stream 流的终结方法
Stream 流的终结方法用于对流进行最终的处理并返回一个结果或副作用。对流进行最终的处理并获取结果。需要注意的是,终结方法只能对流进行一次操作,一旦流被消费,就不能再次使用。
4.1 Stream 流的 forEach 终结方法
对此流运算后的元素执行后遍历。
通过代码具体实现:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class StreamIntermediateMethod {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("张三",19));
list.add(new Student("李四",22));
list.add(new Student("王五",17));
list.add(new Student("张麻子",33));
List<Student> list1 = new ArrayList<>();
list1.add(new Student("李麻子",23));
Stream.concat(list.stream(),list1.stream()).forEach(System.out::println);
}
}
运行结果如下:
4.2 Stream 流的 count() 终结方法
统计此流运算后的元素个数。需要注意的是:返回值是 long 类型。
通过代码具体实现:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class StreamIntermediateMethod {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("张三",19));
list.add(new Student("李四",22));
list.add(new Student("王五",17));
list.add(new Student("张麻子",33));
List<Student> list1 = new ArrayList<>();
list1.add(new Student("李麻子",23));
System.out.println(Stream.concat(list.stream(), list1.stream()).count());
}
}
运行结果如下:
4.3 Stream 流的 max() 或者 min() 终结方法
获取此流运算后的最大值或者最小值元素。但是对于自定义的类型,默认的 max() 方法是不能获取此流的最大值元素,默认的 min() 方法是不能获取此流的最小值元素,会报异常,此时就需要用到比较器了。
通过代码具体实现:
import java.util.ArrayList;
import java.util.List;
public class StreamIntermediateMethod {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("张三", 19));
list.add(new Student("李四", 22));
list.add(new Student("王五", 17));
list.add(new Student("张麻子", 33));
Student s1 = list.stream().max((o1, o2) -> o1.getAge() - o2.getAge()).get();
System.out.println("最大年龄为:"+s1.getAge());
Student s2 = list.stream().min((o1, o2) -> o1.getAge() - o2.getAge()).get();
System.out.println("最小年龄为:"+s2.getAge());
}
}
运行结果如下:
5.0 Stream 流的 collect() 收集方法
把流处理后的结果收集到一个指定的集合中去。
通过代码具体实现:
一. 收集到 list 系列集合中
import java.util.stream.Collectors; import java.util.ArrayList; import java.util.List; public class StreamIntermediateMethod { public static void main(String[] args) { List<Student> list = new ArrayList<>(); list.add(new Student("张三", 19)); list.add(new Student("李四", 22)); list.add(new Student("王五", 17)); list.add(new Student("张麻子", 33)); //对以下代码进行解读:先得到该集合的流,再筛选开头为“张”的名字,得到一个新流,再收集到 List 系列集合中。 List<Student> list1 = list.stream().filter(s->s.getName().startsWith("张")).collect(Collectors.toList()); System.out.println(list1); } }
实现List数组用逗号分隔开,转成字符串
List list = new ArrayList(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); String str = list.stream().collect(Collectors.joining(",")); System.out.println(str); //输出结果为 a,b,c,d
运行结果如下:
二.收集到 Set 系列集合中
import java.util.*;
import java.util.stream.Collectors;
public class StreamIntermediateMethod {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("张三", 19));
list.add(new Student("李四", 22));
list.add(new Student("王五", 17));
list.add(new Student("张麻子", 33));
//对一下代码进行解读: 先得到该集合的流,再进行筛选出年龄大于18的元素,
// 最后再将这些集合中的元素收集到 Set 系列集合中。
Set <Student> set = list.stream().filter(s->s.getAge() > 18).collect(Collectors.toSet());
System.out.println(set);
}
}
运行结果如下:
三.收集到 Map 系列集合中
import java.util.*;
import java.util.stream.Collectors;
public class StreamIntermediateMethod {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("张三", 19));
list.add(new Student("李四", 22));
list.add(new Student("王五", 17));
list.add(new Student("张麻子", 33));
Map<String,Integer> map = list.stream().collect(Collectors.toMap(s-> s.getName(), s-> s.getAge()));
System.out.println(map);
}
}
运行结果如下:
四.收集到数组中
import java.util.*;
public class StreamIntermediateMethod {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("张三", 19));
list.add(new Student("李四", 22));
list.add(new Student("王五", 17));
list.add(new Student("张麻子", 33));
Student[] students = list.stream().toArray(s->new Student[s]);
//以上代码简化为如下:
Student[] students1 = list.stream().toArray(Student[]::new);
System.out.println(Arrays.toString(students));
System.out.println(Arrays.toString(students1));
}
}
运行结果如下: