赞
踩
public class StreamTest01 { public static void main(String[] args) { //定义一个集合 List<String> list = Arrays.asList("张三", "李四", "王五", "张飞吖", "柳先生"); //1.获取所有性张的人 List<String> arr1 = new ArrayList<>(); for (String i : list) { if (i.startsWith("张")) { arr1.add(i); } } System.out.println(arr1); //2.获取性张的,名字长度为3的人 List<String> arr2 = new ArrayList<>(); for (String i : arr1) { if (i.length() == 3) { arr2.add(i); } } System.out.println(arr2); } }
结果:
[张三, 张飞吖]
[张飞吖]
可以看出上面代码针对我们不同的需求,总是去循环遍历集合,这时我们希望有更加高效的处理方式。于是,JDK1.8中提供了Stream API来解决这种弊端。
public class StreamTest02 {
public static void main(String[] args) {
//定义一个集合
List<String> list = Arrays.asList("张三", "李四", "王五", "张飞吖", "柳先生");
list.stream()
//1.获取所有性张的人
.filter(s -> s.startsWith("张"))
//2.获取性张的,名字长度为3的人
.filter(s -> s.length() == 3)
//3.输出
.forEach(System.out::println);
}
}
可以看出上面StreamAPI代码的含义:获取流,根据条件过滤,最后逐一打印。相比之前,它更加的简洁直观。
Stream流式思想是一种将数据处理视为流式操作的编程方式。在Stream中,数据被看作是一个连续的流,通过一系列的中间操作,可以对数据进行转换、过滤、排序等操作,最终得到想要的结果。
Stream流式思想的主要特点是:
延迟执行:Stream中的操作不会立即执行,只有当最终的结果需要被获取时才会执行。这样可以解决一次性处理大量数据带来的内存开销问题。
可组合:Stream中的中间操作可以进行链式调用,形成一个操作流水线,每个操作都是上一个操作的输入,可以方便地组合操作。
可并行:Stream中的操作可以利用多核处理器的特点进行并行处理,提高处理速度。
Stream流式思想广泛应用于Java 8及以上版本,可以在集合、数组等数据结构上进行操作。它使得数据处理更加简洁、高效,并且可以利用现代计算机的并行处理能力,提高程序性能。
注意:
Stream API能让我们快速的完成许多复杂的操作,如筛选、切片、映射、查找、去重、统计、匹配和归纳。
首先,要知道jdk1.8后java.util.Collection中加入了默认方法Stream。
也就是说,Collection接口下的所有实现类都可以通过stream方法来获取Stream流。
public class StreamTest03 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.stream();
HashSet<String> hashSet = new HashSet<>();
hashSet.stream();
Vector<String> vector = new Vector<>();
vector.stream();
}
}
但是,Map接口并没有实现Collection接口。
public class StreamTest03 {
public static void main(String[] args) {
HashMap<String, Object> map = new HashMap<>();
map.keySet().stream();//key
map.values().stream();//value
map.entrySet().stream();//entry
}
}
根据Map获取对应的key value集合,从而获取stream流。
因为在实际开发中,我们无法避免对数组中数据的操作,由于数组对象不可能添加默认方法。所以,Stream接口中提供了静态方法of。
public class StreamTest03 {
public static void main(String[] args) {
//根据Stream的of方法
String[] arr1 = {"a", "b", "c"};
Stream<String> s1 = Stream.of(arr1);
s1.forEach(System.out::println);
int[] arr2 = {1, 2, 3};
Stream<int[]> s2 = Stream.of(arr2);
s2.forEach(System.out::println);
}
}
结果:
a
b
c
[I@214c265e
注意: 基本数据类型的数组是不行的。
Stream API提供的方法是非常丰富的。这些方法大致分为两类:
方法名 | 方法作用 |
---|---|
count | 统计个数 |
forEach | 逐一处理 |
filter | 过滤 |
limit | 取用前几个 |
skip | 跳过前几个 |
map | 映射 |
concat | 组合 |
reduce | 统计 |
max,min | 最值 |
sorted | 排序 |
distinct | 去重 |
终结方法: 返回值类型,不再是Stream类型的方法同时也不再支持链接式调用。
非终结方法: 返回值类型,仍然是Stream类型的方法同时仍然支持持链接式调用。
注意事项:
用来遍历流中的数据。
void forEach(Consumer<? super T> action);
该方法接受一个Consumer接口,并将每一个流元素交给函数处理。
ublic class Method_forEach {
public static void main(String[] args) {
String[] arr1 = {"a", "b", "c"};
Stream<String> s1 = Stream.of(arr1);
s1.forEach(System.out::println);
}
}
用来统计流中元素的个数。
long count();
该方法返回一个long值,代表个数。
public class Method_count {
public static void main(String[] args) {
String[] arr = {"a", "b", "c"};
long count = Stream.of(arr).count();
System.out.println(count);
}
}
用来过滤数据,返回符合条件的数据,通过此方法可以将一个流转换成另一个子集流。
Stream filter(Predicate<? super T> predicate);
该接口接收一个Predicate函数式接口参数作为筛选条件
public class Method_filter {
public static void main(String[] args) {
String[] arr = {"a", "b", "c", "aa"};
Stream<String> s = Stream.of(arr);
s
//筛选流元素中包含a的
.filter(s1 -> s1.contains("a"))
.forEach(System.out :: println);
}
}
可以对流进行截取,只取前n个数据。
Stream limit(long maxSize);
参数是一个long类型的数值,如果集合长度大于参数就进行截取操作,反之不操作。
public class Method_limit {
public static void main(String[] args) {
String[] arr = {"a", "b", "c", "aa"};
Stream<String> s = Stream.of(arr);
//填入的长度不能为负数
s.limit(2).forEach(System.out :: println);
}
}
如果你希望跳过流前面的n个元素,可以使用skip方法获取一个新的流。
Stream skip(long n);
public class Method_skip {
public static void main(String[] args) {
String[] arr = {"a", "b", "c", "aa"};
Stream<String> s = Stream.of(arr);
s.skip(2).forEach(System.out :: println);
}
}
如果你希望将流中的元素映射到另一个流中, 可以使用该方法。
Stream map(Function<? super T, ? extends R> mapper);
该接口需要一个Function函数式接口参数,可以将当前流中的T类型数据转换为另一种R类型数据。
public class Method_map {
public static void main(String[] args) {
Stream<String> stream = Stream.of("1", "2", "3", "4", "5", "6", "7", "8", "9");
stream
// .map( x -> Integer.parseInt(x))
.map(Integer :: parseInt)
.forEach(System.out :: println);
}
}
将数据进行排序。
Stream sorted();
public class Method_sorted {
public static void main(String[] args) {
Stream<Integer> stream = Stream.of(1, 5, 6, 3, 4, 2);
stream
.sorted((o1, o2) -> o2 - o1)//降序,不刻意要求就是升序
.forEach(System.out :: println);
}
}
用来去除重复的数据。
Stream distinct();
Stream流中distinct方法对于基本数据类型是可以直接去重的,但是对于自定义类型,我们需要去重写hashCod和equals方法来移除重复元素。
public class Method_distinct {
public static void main(String[] args) {
String[] arr = {"a", "a", "b", "b"};
Stream.of(arr)
.distinct()
.forEach(System.out :: println);
System.out.println("-----------------------------");
Stream.of(
new Person("MrLiu", 21),
new Person("张三", 22),
new Person("MrLiu", 21)
).distinct().forEach(System.out :: println);
}
}
如果你希望将所有数据归纳得到一个数据,可以使用此方法。
T reduce(T identity, BinaryOperator accumulator);
public class Method_reduce { public static void main(String[] args) { Stream<Integer> stream1 = Stream.of(1, 2, 3, 4); Integer sum = stream1 //identity 默认值 .reduce(0, (x, y) -> { System.out.println("x = " + x + " y = " + y); return x + y; }); System.out.println(sum); System.out.println("---------------------------------------"); Stream<Integer> stream2 = Stream.of(1, 2, 3, 4); Integer max = stream2 //identity 默认值 .reduce(0, (x, y) -> x > y ? x : y ); System.out.println(max); } }
Stream map(Function<? super T, ? extends R> mapper);
public class Method_MapReduce { public static void main(String[] args) { //1.求出所有年龄的总和 Integer sum = Stream.of( new Person("MrLiu", 21), new Person("张三", 22), new Person("MrLiu", 23), new Person("王五", 24) ).map(Person :: getAge) .reduce(0, Integer :: sum); System.out.println(sum); //2.求出所有年龄中的最大值 Integer max = Stream.of( new Person("MrLiu", 21), new Person("张三", 22), new Person("MrLiu", 23), new Person("王五", 24) ).map(Person::getAge) .reduce(0, Math::max); System.out.println(max); //3.统计 1 出现的次数 Integer count = Stream.of(1, 2, 3, 1, 2, 3, 1, 2, 3) .map(x -> x.equals(1) ? 1 : 0) .reduce(0, Integer::sum); System.out.println(count); } }
如果需要将Stream中的Integer类型转换为int类型,可以使用此方法。
IntStream mapToInt(ToIntFunction<? super T> mapper);
public class Method_MapToInt {
public static void main(String[] args) {
//Integer占用的内存比int要多很多,在Stream流操作中会自动装箱和插箱操作。
Integer arr[] = {1, 2, 3, 4};
Stream<Integer> stream = Stream.of(arr);
stream.filter(i -> i > 0).forEach(System.out :: println);
//为了提高程序代码的效率,我们可以先将流中的Integer数据转换为int数据类型,再进行操作
IntStream mapToInt = Stream.of(arr).mapToInt(Integer::intValue);
mapToInt.filter(i -> i > 0).forEach(System.out :: println);
}
}
如果有两个流希望合并为一个流,就可以使用Stream接口的静态方法。
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 class Method_concat {
public static void main(String[] args) {
Stream<String> stream1 = Stream.of("a", "b", "c");
Stream<String> stream2 = Stream.of("d", "e", "f");
Stream<String> concat = Stream.concat(stream1, stream2);
concat.forEach(System.out::println);
}
}
我们前面写的Stream流都属于串行,就是说在一个线程上执行。
/* @Author : MrLiu
* @Date : 19:43 2023/6/15
* 串行流
*/
@org.junit.Test
public void test01(){
Stream.of(5,6,2,1,3,4)
.filter(i -> {
System.out.println(Thread.currentThread().getName() + " " + i);
return i > 3;
}).count();
}
main 5
main 6
main 2
main 1
main 3
main 4
parallelStream其实就是一个并行执行的游戏,它通过默认的ForkJoinPool,可以提高多线程任务的速度。
/* @Author : MrLiu
* @Date : 19:48 2023/6/15
* 并行流
*/
@org.junit.Test
public void test02(){
List<Integer> list = new ArrayList<>();
//通过list接口直接获取并行流
Stream<Integer> integerStream = list.parallelStream();
//将已有的串行流转换为并行流
Stream<Integer> parallel = Stream.of(1, 2, 3).parallel();
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。