设为首页 收藏本站
开启辅助访问 快捷导航
菜单
猿人部落 主页 资讯 查看内容

JAVA基础7-Stream基础学习笔记

2019-7-26 18:06 发布者: 晚起的虫子1 评论 0 查看 776
Stream底子学习条记Stream概念泉源概念特点特性Stream创建方法通过Stream静态方法通过collection方法通过Arrays静态

Stream底子学习条记

  • Stream概念
    • 泉源
    • 概念
    • 特点
    • 特性
  • Stream创建方法
    • 通过Stream静态方法
    • 通过collection方法
    • 通过Arrays静态方法
  • Stream通用语法
  • Stream的常用方法
    • 中心操纵(转换)
      • 无状态操纵
      • 有状态操纵
    • 终极操纵(归纳(reduce))
      • 非短路操纵
      • 短路操纵
  • Comparator
  • Collectors
  • 并行操纵
  • 其他阐明
    • Optional操纵

Stream概念

泉源

Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理处罚数据。
Stream 利用一种雷同用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 聚集运算和表达的高阶抽象。

概念

Stream(流)是一个来自数据源的元素队列并支持聚合操纵
1) 元素是特定范例的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需盘算。
2) 数据源 流的泉源。 可以是聚集,数组,I/O channel, 产生器generator 等。
3) 聚合操纵 雷同SQL语句一样的操纵, 好比filter, map, reduce, find, match, sorted等。

特点

和从前的Collection操纵差别, Stream操纵尚有两个底子的特性:
1) Pipelining: 中心操纵都会返回流对象本身。 如许多个操纵可以串联成一个管道, 如同流式风格(fluent style)。 如许做可以对操纵举行优化, 好比耽误实行(laziness)和短路( short-circuiting)。
2) 内部迭代: 从前对聚集遍历都是通过Iterator大概For-Each的方式, 显式的在聚集外部举行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。

特性

1) stream不存储数据
2) stream不改变源数据
3) stream的耽误实行特性

Stream创建方法

通过Stream静态方法

/**
  * 通过一个Supplier函数,无穷天生对象的聚集流,也是一个无穷流
*/
public static Stream generate(Supplier s);
例子:
Stream.generate(Math::random).limit(10).forEach(System.out::println);
/**
  * 天生无穷长度的Stream,和generator差别的是,其元素的天生是重复对给定的种子值(seed)调用用户指定函数来天生的。此中包罗的元素可以以为是:seed,f(seed),f(f(seed))无穷循环
*/
public static Stream iterate(final T seed, final UnaryOperator f);
例子:
Stream.iterate(1, e->e+2).limit(10).forEach(System.out::println);
/**
  * 通过一个数组获取一个stream,元素为数组的元素,元素必须是对象,而不能是原始数据范例(int、double等)
*/
public static Stream of(T t)
例子:
String[] arrs = new String[]{"a","b","c","d"};
Stream.of(arrs).forEach(System.out::println);
/**
  * 通过多个对象入参获取一个stream,元素是入参对象
*/
public static Stream of(T... values);
例子:
Stream.of(new String("one"),new String("two")).forEach(System.out::println);

通过collection方法

可以用过聚集的接口的默认方法,创建一个流;利用这个方法,包罗继续Collection的接口,如:Set,List等等。

/**
 * 创建一个流
*/
default Stream stream();

/**
 * 创建一个并行流
*/
default Stream parallelStream()

例子:

List strList = new ArrayList();
strList.add("lin");
strList.add("wu");
strList.stream().forEach(System.out::println);
strList.parallelStream().forEach(System.out::println);

通过Arrays静态方法

/**
 * 通过一个数据获取流,这泛型的,还存在int、long和double范例
*/
public static  Stream stream(T[] array);
例子:
Arrays.stream(new int[]{1,2,3,4}).forEach(System.out::println);

Stream通用语法

在这里插入图片形貌
Stream的操纵分为3部分:
第一部分是创建一个stream流(可以参照Stream创建方法)
第二部分是stream流的中心操纵,返回的照旧一个stream流(此部分可以有也可以没有)
第三部分是stream流的终极操纵

Stream的常用方法

中心操纵(转换)

无状态操纵

map(转化元素)

/**
 * 通过实现Function函数接口,遍历转化元素
 */
 Stream map(Function mapper);

filter(过滤元素)

/**
 * 通过实现Predicate函数接口,遍历元素,做过滤利用
 */
Stream filter(Predicate predicate);

flatMap(拆解元素)

/**
 * 将每个元素作为传播进Function中,末了归入父类流内里
 */
 Stream flatMap(Function> mapper);

peek(监视元素)

/**
 * 此方法重要用于支持调试,您盼望在元素流经管道中的某个点时查察元素
 */
Stream peek(Consumer action);

有状态操纵

limit(截取元素)

/**
 * 将取流的前几个元素
 */
Stream limit(long maxSize);

sorted(排序元素)

/**
 * 将元素通过天然排序,其元素必须实现Comparable接口
 */
Stream sorted();

/**
 * 将元素通过本身实现的Comparable接口举行排序
 */
Stream sorted(Comparator comparator);

distinct(去重元素)

/**
 * 将元素做去重操纵,利用equals作为比力
 */
Stream distinct();

skip(跳过元素)

/**
 * 跳过前n个元素
 */
Stream skip(long n);

终极操纵(归纳(reduce))

非短路操纵

max(最大值)

/**
 * 通过一个Comparator接口,返回最大值元素
 */
Optional max(Comparator comparator);

min(最小值)

/**
 * 通过一个Comparator接口,返回最小值元素
 */
Optional min(Comparator comparator);

count(数量)

/**
 * 获取元素个数
 */
long count();

reduce(归纳)
明白为归档函数,简朴明白为末了获取一个归纳的值(大概是总和、最大值、最小值等),前面全部函数都可以通过reduce实现,而之以是有上面的函数,是由于常用才界说出来。

/**
 * identity为初始值,然后通过BinaryOperator操纵,得到末了的值(与元素雷同范例)
 */
T reduce(T identity, BinaryOperator accumulator);
例子:实现sum操纵
int[] arrInt = {1,3,4,2};
System.out.println("ints sum is:" + Arrays.stream(arrInt).reduce(0, (sum, item) -> sum + item));

/**
 * 没有初始值,然后通过BinaryOperator操纵,得到末了的值(是一个Optional值)
 */
Optional reduce(BinaryOperator accumulator);
例子:实现max操纵
int[] arrInt = {1,3,4,2};
System.out.println("ints max is:" + Arrays.stream(arrInt).reduce(0, (item1, item2) -> item1 >item2?item1:item2));

/**
 * identity为初始值
* 当stream黑白并行操纵时,用法与2个参数的reduce根本一样,通过BiFunction操纵,得到末了的值(与元素的范例不愿定雷同)
* 当stream是并行操纵时,先是每个线程利用初始值identity分别举行BiFunction操纵,再将得到的每个结果举行BinaryOperator操纵
 */
 U reduce(U identity,
                 BiFunction accumulator,
                 BinaryOperator combiner);

例子1:通过非并行实现过滤filter操纵

List ints = Arrays.asList(1,2,3,4,5,6,7,8,9,10);		 BiFunction,Integer,ArrayList> bifun = new BiFunction,Integer,ArrayList>(){
			@Override
			public ArrayList apply(ArrayList t, Integer u) {
				if(u<5)
					t.add(u);
				return t;
			}
			 
		 };
BinaryOperator> binaryOper = new BinaryOperator>() {
			@Override
			public ArrayList apply(ArrayList strings, ArrayList strings2) {
				return strings;  
			}
		};
System.out.println("ints filter less than 5 is:" + ints.stream().reduce(new ArrayList(),bifun,binaryOper));

collect(网络)
可以明白与reduce一样,但是实现方式大概差别,reduce中通过BiFunction有返回值,而collect通过BiConsumer没有返回值,大概造成影响是对于原始数据范例和String,在collect中每一次BiConsumer操纵都无法保存。reduce恰当不可变容器归约,collect恰当可变容器归约。collect恰当并行。

/**
 * supplier为初始值,但与reduce差别是它继承一个表达式
* accumulator,对每个元素举行操纵
* combiner,将全部线程结果举行combiner操纵
 */
 R collect(Supplier supplier,
                  BiConsumer accumulator,
                  BiConsumer combiner);
/**
 * 通过Collector工具类实现与上面方法划一结果
 */
 R collect(Collector collector);

例子:实现filter功能

List ints = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
System.out.println("ints filter less than 5 is:" + ints.stream().parallel().collect(()->new ArrayList(), (array, ar) -> {if (ar<5) array.add(ar);}, (array1, array2) -> array1.addAll(array2)));

短路操纵

findFirst(第一个元素)

/**
 * 获取第一个元素
 */
Optional findFirst();

findAny(恣意一个元素)

/**
 * 返回这个集会合,取到的任何一个对象。在串行流中取第一个,在并行流中随机取。
 */
Optional findAny();

anyMatch(任何一个元素符合条件)

/**
 * 元素中只要一个符合predicate条件,即返回true
 */
boolean anyMatch(Predicate predicate);

allMatch(全部元素符合条件)

/**
 * 全部元素中都符合predicate条件,即返回true
 */
boolean allMatch(Predicate predicate);

noneMatch(没有元素符合条件)

/**
 * 全部元素中都不符合predicate条件,即返回true
 */
boolean noneMatch(Predicate predicate);

Comparator

Comparator接口,提供了一下静态方法获取comparator。
1) Comparator.reverseOrder()) 天然排序的逆向排序
2) Comparator.comparing(Student::getAge))利用某个属性排序
3) Comparator.comparing(Student::getAge).reversed(),逆向排序
一样平常用于sort操纵

Collectors

Collectors 类实现了许多归约操纵,比方将流转换成聚集和聚合元素。Collectors 可用于返回列表或字符串。一样平常用于collect操纵中。
toList(转换为List)

/**
 * 将stream转化为一个List
 */
public static  Collector> toList();

toSet(转换为Set)

/**
 * 将stream转化为一个Set
 */
public static  Collector> toSet();

toMap(转换为Map)

/**
 * 将stream转化为一个Map
* keyMapper,是获取key的一个function,假如元素的key存在一样,会报java.lang.IllegalStateException。这是由于没有传入mergeFunction,利用默认的throwingMerger。
* valueMapper,是获取value的一个function
 */
public static 
    Collector> toMap(Function keyMapper,
                                    Function valueMapper);

/**
 * 将stream转化为一个Map
* keyMapper,是获取key的一个function,假如元素的key存在一样,会报java.lang.IllegalStateException
* valueMapper,是获取value的一个function
* mergeFunction,一个BinaryOperator,管理一个重复key报错标题
 */
public static 
    Collector> toMap(Function keyMapper,
                                    Function valueMapper,
                                    BinaryOperator mergeFunction);

/**
 * 将stream转化为一个Map
* keyMapper,是获取key的一个function,假如元素的key存在一样,会报java.lang.IllegalStateException
* valueMapper,是获取value的一个function
* mergeFunction,一个BinaryOperator,管理一个重复key报错标题
* mapSupplier,指定返回Map范例,假如没有,默以为HashMap。
 */
public static >
    Collector toMap(Function keyMapper,
                                Function valueMapper,
                                BinaryOperator mergeFunction,
                                Supplier mapSupplier)

例子:

List list = new ArrayList();
list.add(new Person(1, "haha"));
list.add(new Person(2, "rere"));
list.add(new Person(3, "fefe"));
list.add(new Person(1, "linwu"));
list.add(new Person(4, null));
Map mapp = list.stream().collect(Collectors.toMap(Person::getId, Function.identity(),(k,v)->v));
System.out.println(mapp);
System.out.println(mapp.get(1).getName());

averaging(获取均匀值)
有三种,分别为averagingInt、averagingLong、averagingDouble。返回均匀值。
summarizing(获取统计信息)
有三种,分别为summarizingInt、summarizingLong、summarizingDouble。返回一个统计信息,包罗个数,总数等。
groupingBy(分组)
分组功能,返回一个Map,key为泛型,value为一个List。有三种范例,可以支持多层分组。
partitioningBy(分区)
分区功能,是分组功能的一种特殊情况,其map的key是boolean,以是只有true和false。可以支持多层分组。

并行操纵

根据预估的数据量获取最小处理处罚单元的巨细阈值,即当数据量已经小于这个阈值的时间举行盘算,否则举行fork 将使命分别成更小的数据块,举行求解。这里值得注意的是,getTargetSize 在第一次调用的时间会设置:
推测数据量巨细 / (默认并发度 * 4) 的结果作为最小实行单元的数量(设置的默认值是cpu 数 – 1,可以通过java.util.concurrent.ForkJoinPool.common.parallelism设置)

其他阐明

Optional操纵

通常聚合操纵会返回一个Optional范例,Optional表现一个安全的指定结果范例,所谓的安全指的是制止直接调用返回范例的null值而造成空指针非常,调用optional.ifPresent()可以判定返回值是否为空,大概直接调用ifPresent(Consumer consumer)在结果部位空时举行消耗操纵;调用optional.get()获取返回值。



路过

雷人

握手

鲜花

鸡蛋
收藏 邀请
上一篇:GOF23设计模式-单例模式-5种实现方式比较和防止反射与反序列化漏洞下一篇:抖音视频置顶?抖音视频置顶功能全解!

相关阅读

一周热门

头条攻略!

日排行榜

相关分类