Java SE入门及基础(55)& Stream流及常用API

目录

第一节 Stream 流

1. 管道

2.如何获取 Stream 流

Collection 接口

Stream 接口

示例

3. Stream 流中间聚合操作

Stream 接口

示例

4. Stream 流终结操作

示例

5. Stream 流聚合操作与迭代器的区别

面试题


第一节 Stream

1. 管道

        管道

A pipeline is a sequence of aggregate operations.
管道就是一系列的聚合操作。
A pipeline contains the following components:
管道包含以下组件:
        A source: This could be a collection, an array, a generator function, or an I/O channel.
        源:可以是集合,数组,生成器函数或I / O 通道。
        Zero or more intermediate operations. An intermediate operation, such as filter, produces a new stream.
        零个或多个中间操作。诸如过滤器之类的中间操作产生新的流。
        A terminal operation. A terminal operation, such as forEach, produces a non-stream result, such as a primitive value (like a double value), a collection, or in the case of forEach, no value at all.
        终结操作。终端操作(例如forEach )会产生非流结果,例如原始值(如双精度值),集合,或者在forEach的情况下根本没有任何值。

         

A stream is a sequence of elements. Unlike a collection, it is not a data structure that stores elements. Instead, a stream carries values from a source through a pipeline.
流是一系列元素。 与集合不同,它不是存储元素的数据结构。 取而代之的是,流通过管道携带来自源的值。
The filter operation returns a new stream that contains elements that match its predicate (this operation's parameter).
筛选器操作返回一个新流,该流包含与筛选条件(此操作的参数)匹配的元素。

2.如何获取 Stream

Collection 接口

default Stream < E > stream ();

Stream 接口

// 获取流
public static < T > Stream < T > of ( T ... values );
// 将两个流拼接形成一个新的流
public static < T > Stream < T > concat ( Stream <? extends T > a , Stream <? extends T > b );

示例

import java . util . Arrays ;
import java . util . HashMap ;
import java . util . List ;
import java . util . Map ;
import java . util . stream . Stream ;
public class StreamTest {
        public static void main ( String [] args ) {
                List < Integer > numbers1 = Arrays . asList ( 1 , 2 , 3 , 4 , 5 );
                Stream < Integer > s1 = numbers1 . stream ();
                Stream < Integer > s2 = Stream . of ( 6 , 7 , 8 , 9 , 10 );
                Stream < Integer > s3 = Stream . concat ( s1 , s2 );
                Map < String , Integer > map = new HashMap <> ();
                map . put ( "a" , 1 );
                map . put ( "b" , 2 );
                Stream < Map . Entry < String , Integer >> s4 = map . entrySet (). stream ();
        }
}

3. Stream 流中间聚合操作

Stream 接口

Stream < T > filter ( Predicate <? super T > predicate ); // 根据给定的条件过滤流中的元素
< R > Stream < R > map ( Function <? super T , ? extends R > mapper ); // 将流中元素进行类型转换
Stream < T > distinct (); // 去重
Stream < T > sorted (); // 排序,如果存储元素没有实现 Comparable 或者相关集合没有提供 Comparator将抛出异常
Stream < T > limit ( long maxSize ); // 根据给定的上限,获取流中的元素
Stream < T > skip ( long n ); // 跳过给定数量的元素
IntStream mapToInt ( ToIntFunction <? super T > mapper ); // 将流中元素全部转为整数
LongStream mapToLong ( ToLongFunction <? super T > mapper ); // 将流中元素全部转为长整数
DoubleStream mapToDouble ( ToDoubleFunction <? super T > mapper ); // 将流中元素全部转为双精度浮点数

示例

import java . util . Arrays ;
import java . util . List ;
import java . util . Set ;
import java . util . function . Function ;
import java . util . function . IntFunction ;
import java . util . function . Predicate ;
import java . util . stream . Collectors ;
import java . util . stream . Stream ;
public class AggregateOperation {
        public static void main ( String [] args ) {
                // List<Integer> numbers = Arrays.asList(30,21,58,67,90,72);
                // for(Integer number: numbers){
                        // if(number % 2 == 0){
                                // System.out.println(number);
                        // }
                // }
                Stream < Integer > s1 = Stream . of ( 30 , 21 , 58 , 67 , 90 , 72 , 58 , 30 , 80 );
                // Stream<Integer> s2 = s1.filter(new Predicate<Integer>() {
                // @Override
                // public boolean test(Integer integer) {
                        // return integer % 2 == 0;
                // }
        // });
        Stream < String > s2 = s1 . filter ( number -> number % 2 == 0 ). distinct (). skip ( 1 ). sorted (). limit ( 2 ). map ( integer -> " 字符串 " + integer );
        s2 . forEach ( System . out :: println );
        //将流中的元素收集为一个 List 集合,此时流就已经消亡了
        // List<Integer> existNumbers = s2.collect(Collectors.toList());
        //再使用流进行收集操作时就将报错
        // Set<Integer> set = s2.collect(Collectors.toSet());
        // Integer[] arr = s2.toArray(new IntFunction<Integer[]>() {
        // @Override
        // public Integer[] apply(int value) {
                // return new Integer[value];
        // }
        // });
        //再使用流进行收集操作时就将报错
        // Integer[] arr = s2.toArray(Integer[]::new);
        // for(Integer number: arr){
                // System.out.println(number);
        // }
        }
}
import java . util . Arrays ;
import java . util . stream . DoubleStream ;
import java . util . stream . IntStream ;
import java . util . stream . LongStream ;
import java . util . stream . Stream ;
public class NumberStream {
        public static void main ( String [] args ) {
                Stream < String > s1 = Stream . of ( "1" , "2" , "3" , "4" );
                // IntStream s2 = s1.mapToInt(new ToIntFunction<String>() {
                // @Override
                // public int applyAsInt(String value) {
                        // return Integer.parseInt(value);
                // }
        // });
                // IntStream s2 = s1.mapToInt(value->Integer.parseInt(value));
                IntStream s2 = s1 . mapToInt ( Integer :: parseInt );
                int [] arr = s2 . toArray ();
                System . out . println ( Arrays . toString ( arr ));
                LongStream s3 =
                Stream . of ( "1" , "2" , "3" , "4" ). mapToLong ( Long :: parseLong );
                long [] arr2 = s3 . toArray ();
                System . out . println ( Arrays . toString ( arr2 ));
                DoubleStream s4 =
                Stream . of ( "1" , "2" , "3" , "4" ). mapToDouble ( Double :: parseDouble );
                double [] arr3 = s4 . toArray ();
                System . out . println ( Arrays . toString ( arr3 ));
        }
}

4. Stream 流终结操作

void forEach ( Consumer <? super T > action ); // 遍历操作流中元素
< A > A [] toArray ( IntFunction < A [] > generator ); // 将流中元素按照给定的转换方式转换为数组
< R , A > R collect ( Collector <? super T , A , R > collector ); // 将流中的元素按照给定的方式搜集起来
Optional < T > min ( Comparator <? super T > comparator ); // 根据给定的排序方式获取流中最小元素
Optional < T > max ( Comparator <? super T > comparator ); // 根据给定的排序方式获取流中最大元素
Optional < T > findFirst (); // 获取流中第一个元素
long count (); // 获取流中元素数量
boolean anyMatch ( Predicate <? super T > predicate ); // 检测流中是否存在给定条件的元素
boolean allMatch ( Predicate <? super T > predicate ); // 检测流中元素是否全部满足给定条件
boolean noneMatch ( Predicate <? super T > predicate ); // 检测流中元素是否全部不满足给定条件

示例

import java . util . Arrays ;
import java . util . List ;
import java . util . Optional ;
import java . util . Set ;
import java . util . function . Function ;
import java . util . function . IntFunction ;
import java . util . function . Predicate ;
import java . util . stream . Collectors ;
import java . util . stream . Stream ;
public class AggregateOperation {
        public static void main ( String [] args ) {
                List < String > numbers =
                Arrays . asList ( "30" , "21" , "58" , "67" , "90" , "72" );
                // Stream<String> s = numbers.stream();
                // Optional<String> first = s.findFirst();
                // System.out.println(first.get());
                // Optional<String> optional = s.max(String::compareTo);
                // String max = optional.get();
                // System.out.println(max);
                // System.out.println(s.count());
                // numbers.stream().map(new Function<String, Integer>() {
                // @Override
                // public Integer apply(String s) {
                        // return Integer.parseInt(s);
                // }
                // }).anyMatch(new Predicate<Integer>() {
                // @Override
                // public boolean test(Integer integer) {
                        // return integer % 2 == 1;
                // }
        // });
                boolean exist1 =
                numbers . stream (). map ( Integer :: parseInt ). anyMatch ( number -> number % 2 == 1 );
                System . out . println ( exist1 );
                boolean exist2 =
                numbers . stream (). map ( Integer :: parseInt ). allMatch ( number -> number % 2 == 1 );
                System . out . println ( exist2 );
                boolean exist3 =
                numbers . stream (). map ( Integer :: parseInt ). noneMatch ( number -> number % 2 == 1 );
                System . out . println ( exist3 );
        }
}

5. Stream 流聚合操作与迭代器的区别

Aggregate operations, like forEach, appear to be like iterators. However, they have several fundamental differences:
聚合操作(如 forEach )似乎像迭代器。但是,它们有几个基本差异:
They use internal iteration: Aggregate operations do not contain a method like next to instruct them to process the next element of the collection. With internal delegation, your application determines what collection it iterates, but the JDK determines how to iterate the collection. With external iteration, your application determines both what collection it iterates and how it iterates it. However, external iteration can only iterate over the elements of a collection sequentially. Internal iteration does not have this limitation. It can more easily take advantage of parallel computing, which involves dividing a problem into subproblems, solving those problems simultaneously, and then combining the results of the solutions to the subproblems.
它们使用内部迭代:聚合操作不包含诸如 next 的方法来指示它们处理集合的下一个元素。使用内部委托,你的应用程序确定要迭代的集合,而JDK 确定如何迭代该集合。通过外部迭代,你的应用程序既可以确定要迭代的集合,又可以确定迭代的方式。但是,外部迭代只能顺序地迭代集合的元素。内部迭代没有此限制。它可以更轻松地利用并行计算的优势,这涉及将问题分为子问题,同时解决这些问题,然后将解决方案的结果组合到子问题中。
They process elements from a stream: Aggregate operations process elements from a stream, not directly from a collection. Consequently, they are also called stream operations.
它们处理流中的元素:聚合操作从流中而不是直接从集合中处理元素。因此,它们也称为流操作。
They support behavior as parameters: You can specify lambda expressions as parameters for most aggregate operations. This enables you to customize the behavior of a particular aggregate operation.
它们支持将行为作为参数:你可以将 lambda 表达式指定为大多数聚合操作的参数。这使你可以自定义特定聚合操作的行为。

面试题

        使用Stream 流将一个基本数据类型的数组转换为包装类型的数组,再将包装类型的数组转换基本数据类型数组。
int [] intArr1 = { 1 , 2 , 3 , 4 , 5 };
        // Integer[] intArr2 = Arrays.stream(intArr1).mapToObj(new IntFunction<Integer>() {
                // @Override
                // public Integer apply(int value) {
                        // return value;
                // }
                // }).toArray(new IntFunction<Integer[]>() {
                // @Override
                // public Integer[] apply(int value) {
                        // return new Integer[value];
                // }
        // });
        // Integer[] intArr2 = Arrays.stream(intArr1).mapToObj(value ->value).toArray(Integer[]::new);
Integer [] intArr2 = Arrays . stream ( intArr1 ). boxed (). toArray ( Integer []:: new );
Integer [] intArr3 = { 1 , 2 , 3 , 4 , 5 };
int [] intArr4 =
Arrays . stream ( intArr3 ). mapToInt ( Integer :: intValue ). toArray ();

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值