常用方法
方法名 | 方法作用 | 返回值类型 | 方法种类 |
---|---|---|---|
count | 统计个数 | long | 终结 |
forEach | 逐一处理 | void | 终结 |
filter | 过滤 | Stream | 非终结 |
limit | 取用前几个 | Stream | 非终结 |
skip | 跳过前几个 | Stream | 非终结 |
map | 映射 | Stream | 非终结 |
concat | 组合 | Stream | 非终结 |
"终结"方法指的是返回值类型不再是 Stream 类型的方法,它们不支持链式调用。
"非终结"方法指的是返回值类型仍然是 Stream 类型的方法,它们支持链式调用。
注意
- Stream只能操作一次
- Stream方法返回的是新的流
- Stream不调用终结方法,中间的操作不会执行
1. forEach
forEach
用来遍历流中的数据的
void forEach(Consumer<? super T> action);
该方法接受一个 Consumer
接口,会将每一个流元素交给函数处理
public static void main(String[] args) {
Stream.of("a1", "a2", "a3").forEach(System.out::println);;
}
2. count
Stream流中的 count
方法用来统计其中的元素个数的
long count();
该方法返回一个 long
值,代表元素的个数。
public static void main(String[] args) {
long count = Stream.of("a1", "a2", "a3").count();
System.out.println(count);
}
3. filter
filter
方法的作用是用来过滤数据的。返回符合条件的数据
可以通过 filter
方法将一个流转换成另一个子集流
Stream<T> filter(Predicate<? super T> predicate);
该接口接收一个 Predicate
函数式接口参数作为筛选条件
javaCopy codepublic static void main(String[] args) {
Stream.of("a1", "a2", "a3","bb","cc","aa","dd")
.filter((s)->s.contains("a"))
.forEach(System.out::println);
}
Output:
a2
a3
aa
4.limit

limit方法可以对流进行截取处理,支取前n个数据
Stream<T> limit(long maxSize);
参数是一个long类型的数值,如果集合当前长度大于参数就进行截取,否则不操作
Stream<T> limit(long maxSize);
javaCopy codepublic static void main(String[] args) {
Stream.of("a1", "a2", "a3","bb","cc","aa","dd")
.limit(3)
.forEach(System.out::println);
}
Output:
a1
a2
a3
5. skip

如果希望跳过前面几个元素,可以使用 skip
方法获取一个截取之后的新流:
Stream<T> skip(long n);
操作:
javaCopy codepublic static void main(String[] args) {
Stream.of("a1", "a2", "a3","bb","cc","aa","dd")
.skip(3)
.forEach(System.out::println);
}
Output:
bb
cc
aa
dd
6. map
如果我们需要将流中的元素映射到另一个流中,可以使用 map
方法:
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
提示
?
是通配符,表示任意类型。在 Function<? super T, ? extends R>
中,? super T
表示接受 T
或 T
的超类作为参数,? extends R
表示返回 R
或 R
的子类
该接口需要一个 Function
函数式接口参数,可以将当前流中的 T
类型数据转换为另一种 R
类型的数据
javaCopy codepublic static void main(String[] args) {
Stream.of("1", "2", "3","4","5","6","7")
.map(Integer::parseInt)
.forEach(System.out::println);
}
7. sorted
如果需要将数据排序,可以使用 sorted
方法:
Stream<T> sorted();
在使用的时候可以根据自然规则排序,也可以通过比较强来指定对应的排序规则
javaCopy codepublic static void main(String[] args) {
Stream.of("1", "3", "2","4","0","9","7")
.map(Integer::parseInt)
//.sorted() // 根据数据的自然顺序排序
.sorted((o1,o2)->o2-o1) // 根据比较强指定排序规则
.forEach(System.out::println);
}
8. distinct

如果要去掉重复数据,可以使用 distinct
方法:
Stream<T> distinct();
Stream流中的distinct方法对于基本数据类型是可以直接去重的,但是对于自定义类型,我们是需要重写 hashCode
和 equals
方法来移除重复元素。
public static void main(String[] args) {
Stream.of("1", "3", "3","4","0","1","7")
.map(Integer::parseInt)
//.sorted() // 根据数据的自然顺序排序
.sorted((o1,o2)->o2-o1) // 根据比较强指定排序规则
.distinct() // 去掉重复的记录
.forEach(System.out::println);
System.out.println("--------");
Stream.of(
new Person("张三",18)
,new Person("李四",22)
,new Person("张三",18)
).distinct()
.forEach(System.out::println);
}
9. match
如果需要判断数据是否匹配指定的条件,可以使用 match
相关的方法
使用
boolean anyMatch(Predicate<? super T> predicate); // 元素是否有任意一个满足条件
boolean allMatch(Predicate<? super T> predicate); // 元素是否都满足条件
boolean noneMatch(Predicate<? super T> predicate); // 元素是否都不满足条件
注意: match
是一个终结方法
public static void main(String[] args) {
boolean b = Stream.of("1", "3", "3", "4", "5", "1", "7")
.map(Integer::parseInt)
//.allMatch(s -> s > 0)
//.anyMatch(s -> s >4)
.noneMatch(s -> s > 4);
System.out.println(b);
}
10. find

如果我们需要找到某些数据,可以使用 find
方法来实现
Optional<T> findFirst();
Optional<T> findAny();
使用:
public static void main(String[] args) {
Optional<String> first = Stream.of("1", "3", "3", "4", "5", "1", "7").findFirst();
System.out.println(first.get());
Optional<String> any = Stream.of("1", "3", "3", "4", "5", "1", "7").findAny();
System.out.println(any.get());
}
11. max和min
如果我们想要获取最大值和最小值,那么可以使用 max
和 min
方法
Optional<T> min(Comparator<? super T> comparator);
Optional<T> max(Comparator<? super T> comparator);
public static void main(String[] args) {
//max
Optional<Integer> max = Stream.of("1", "3", "3", "4", "5", "1", "7")
.map(Integer::parseInt)
.max((o1,o2)->o1-o2);
System.out.println(max.get());
//min
Optional<Integer> min = Stream.of("1", "3", "3", "4", "5", "1", "7")
.map(Integer::parseInt)
.min((o1,o2)->o1-o2);
System.out.println(min.get());
}
12. reduce

如果需要将所有数据归纳得到一个数据,可以使用 reduce
方法
T reduce(T identity, BinaryOperator<T> accumulator);
public static void main(String[] args) {
Integer sum = Stream.of(4, 5, 3, 9)
// identity默认值
// 第一次的时候会将默认值赋值给x
// 之后每次会将上一次的操作结果赋值给x,y就是每次从数据中获取的元素
.reduce(0, (x, y) -> {
System.out.println("x="+x+",y="+y);
return x + y;
});
System.out.println(sum);
// 获取最大值
Integer max = Stream.of(4, 5, 3, 9)
.reduce(0, (x, y) -> {
return x > y ? x : y;
});
System.out.println(max);
}
Output:
x=0,y=4
x=4,y=5
x=9,y=3
x=12,y=9
21
9//最大值
13.map和reduce的组合
在实际开发中我们经常会将map和reduce一块来使用
public static void main(String[] args) {
Integer sumAge = Stream.of(
new Person("张三", 18)
, new Person("李四", 22)
, new Person("张三", 13)
, new Person("王五", 15)
, new Person("张三", 19)
).map(Person::getAge)
.reduce(0, Integer::sum);
System.out.println(sumAge);
Integer maxAge = Stream.of(
new Person("张三", 18)
, new Person("李四", 22)
, new Person("张三", 13)
, new Person("王五", 15)
, new Person("张三", 19)
).map(Person::getAge)
.reduce(0, Math::max);
System.out.println(maxAge);
//有多少个'a'
Integer count = Stream.of("a", "b", "c", "d", "a", "c", "a")
.map(ch -> "a".equals(ch) ? 1 : 0)
.reduce(0, Integer::sum);
System.out.println(count);
}
Output:
87
22
3
14. mapToInt
如果需要将Stream中的Integer类型转换成int类型,可以使用mapToInt方法来实现

public static void main(String[] args) {
// Integer占用的内存比int多很多,在Stream流操作中会自动装修和拆箱操作
Integer[] arr = {1,2,3,5,6,8};
Stream.of(arr)
.filter(i->i>0)
.forEach(System.out::println);
System.out.println("---------");
// 为了提高程序代码的效率,我们可以先将流中Integer数据转换为int数据,然后再操作
IntStream intStream = Stream.of(arr)
.mapToInt(Integer::intValue);
intStream.filter(i->i>3)
.forEach(System.out::println);
}
15. concat
public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) {
Objects.requireNonNull(a);
Objects.requireNonNull(b);
@SuppressWarnings("unchecked")//告诉编译器忽略特定类型转换的警告
Spliterator<T> split = new Streams.ConcatSpliterator.OfRef<>(
(Spliterator<T>) a.spliterator(), (Spliterator<T>) b.spliterator());
Stream<T> stream = StreamSupport.stream(split, a.isParallel() || b.isParallel());
return stream.onClose(Streams.composedClose(a, b));
}
使用:
public static void main(String[] args) {
Stream<String> stream1 = Stream.of("a","b","c");
Stream<String> stream2 = Stream.of("x", "y", "z");
// 通过concat方法将两个流合并为一个新的流
Stream.concat(stream1,stream2).forEach(System.out::println);
}