概念:

Steam 是Java8 提出的一个新概念,不是输入输出的 Stream 流,而是一种用函数式编程方式在集合类上进行复杂操作的工具。简而言之,是以内部迭代的方式处理集合数据的操作,内部迭代可以将更多的控制权交给集合类。Stream 和 Iterator 的功能类似,只是 Iterator 是以外部迭代的形式处理集合数据的操作。

在Java8以前,对集合的操作需要写出处理的过程,如在集合中筛选出满足条件的数据,需要一 一遍历集合中的每个元素,再把每个元素逐一判断是否满足条件,最后将满足条件的元素保存返回。而Stream 对集合筛选的操作提供了一种更为便捷的操作,只需将实现函数接口的筛选条件作为参数传递进来,Stream会自行操作并将合适的元素同样以stream 的方式返回,最后进行接收即可。

2种操作:

1.intermediate operation 中间操作:中间操作的结果是刻画、描述了一个Stream,并没有产生一个新集合,这种操作也叫做惰性求值方法。

2.terminal operation 终止操作:最终会从Stream中得到值。

如何区分这2种操作呢?可以根据操作的返回值类型判断,如果返回值是Stream,则该操作是中间操作,如果返回值是其他值或者为空,则该操作是终止操作。

flatMap 中间操作:

可用 Stream 替换值,并将多个 Stream 流合并成一个 Stream 流。

将含有一串数字的两个流合并为一个流,

@Test

public void flapMapTest() {

List list = (List) Stream.of(Arrays.asList(1, 2, 3, 4, 5, 6), Arrays.asList(8, 9, 10, 11, 12))

.flatMap(test -> test.stream()).collect(Collectors.toList());

for (int i = 0, length = list.size(); i < length; i++) {

System.out.println(list.get(i));

}

}

flatMap的用法和含义住要通过一个案例来讲解,

案例:对给定单词列表 ["Hello","World"],你想返回列表["H","e","l","o","W","r","d"]

第一种方式

String[] words = new String[]{"Hello","World"};

List a = Arrays.stream(words)

.map(word -> word.split(""))

.distinct()

.collect(toList());

a.forEach(System.out::print);

代码输出为:

[Ljava.lang.String;@12edcd21[Ljava.lang.String;@34c45dca

(返回一个包含两个String[]的list)

这个实现方式是由问题的,传递给map方法的lambda为每个单词生成了一个String[](String列表)。因此,map返回的流实际上是Stream 类型的。你真正想要的是用Stream来表示一个字符串。

下方图是上方代码stream的运行流程

第二种方式:flatMap(对流扁平化处理)

String[] words = new String[]{"Hello","World"};

List a = Arrays.stream(words)

.map(word -> word.split(""))

.flatMap(Arrays::stream)

.distinct()

.collect(toList());

a.forEach(System.out::print);

结果输出:HeloWrd

使用flatMap方法的效果是,各个数组并不是分别映射一个流,而是映射成流的内容,所有使用map(Array::stream)时生成的单个流被合并起来,即扁平化为一个流。

下图是运用flatMap的stream运行流程,

示例:

import java.util.ArrayList;

import java.util.Arrays;

import java.util.List;

import java.util.stream.Collectors;

public class FlatMap {

public static void main(String[] args) {

//扁平化流

//找出数组中唯一的字符

String[] strArray = {"hello", "world"};

//具体实现

List res = Arrays.stream(strArray)

.map(w -> w.split(""))

.flatMap(Arrays::stream)

.distinct()

.collect(Collectors.toList());

System.out.println(res);

//TODO 案例

System.out.println("--------------------------------");

//Demo1:给定数组,返回数组平方和(直接使用映射)

//[1,2,3,4]=>[1,4,9,16]

Integer[] nums1 = {1, 2, 3, 4};

List nums1List = Arrays.asList(nums1);

List res1 = nums1List.stream().map(i -> i * i).collect(Collectors.toList());

System.out.println(res1);

System.out.println("--------------------------------");

//Demo2:给定两数组,返回数组对

//[1,2,3],[3,4]=>[1,3],[1,4],[2,3],[2,4],[3,3],[3,4]

Integer[] nums2 = {1, 2, 3};

Integer[] nums3 = {3, 4};

List nums2List = Arrays.asList(nums2);

List nums3List = Arrays.asList(nums3);

//使用2个map嵌套过滤

List res2 = nums2List.stream().flatMap(i -> nums3List.stream().map(j -> new int[]{i, j})).collect(Collectors.toList());

System.out.println(res2.size());

System.out.println("--------------------------------");

//Demo3:针对Demo2和Demo1组合返回总和能被3整除的数对

//(2,4)和(3,3)是满足条件的

List res3 = nums2List.stream().flatMap(i -> nums3List.stream().filter(j -> (i + j) % 3 == 0).map(j -> new int[]{i, j})).collect(Collectors.toList());

System.out.println(res3.size());

}

}

控制台输出结果:

补充知识:Java 之 Stream流中map和flatMap的区别

我们先来看 map。如果你熟悉 scala 这类函数式语言,对这个方法应该很了解,它的作用就是把 input Stream 的每一个元素,映射成 output Stream 的另外一个元素。

转换大写

List output = wordList.stream().

map(String::toUpperCase).

collect(Collectors.toList());

这段代码把所有的单词转换为大写。

平方数

List nums = Arrays.asList(1, 2, 3, 4);

List squareNums = nums.stream().

map(n -> n * n).

collect(Collectors.toList());

这段代码生成一个整数 list 的平方数 {1, 4, 9, 16}。

从上面例子可以看出,map 生成的是个 1:1 映射,每个输入元素,都按照规则转换成为另外一个元素。还有一些场景,是一对多映射关系的,这时需要 flatMap。

一对多

Stream> inputStream = Stream.of(

Arrays.asList(1),

Arrays.asList(2, 3),

Arrays.asList(4, 5, 6)

);

Stream outputStream = inputStream.

flatMap((childList) -> childList.stream());

flatMap 把 inpuStream 中的层级结构扁平化,就是将最底层元素抽出来放到一起,最终 output 的新 Stream 里面已经没有 List 了,都是直接的数字。

以上这篇浅谈java8 stream flatMap流的扁平化操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

java双层list扁平化,浅谈java8 stream flatMap流的扁平化操作相关推荐

  1. java 扁平化_java8 stream flatMap流的扁平化操作

    概念:Steam 是Java8 提出的一个新概念,不是输入输出的 Stream 流,而是一种用函数式编程方式在集合类上进行复杂操作的工具.简而言之,是以内部迭代的方式处理集合数据的操作,内部迭代可以将 ...

  2. 【转】图标字体化浅谈

    在做手机端Web App项目中,经常会遇到小图标在手机上显示比较模糊的问题,经过实践发现了一种比较好的解决方案,图标字体化.在微社区项目中,有很多小的Icon(图标),如分享.回复.赞.返回.话题.访 ...

  3. java 中的单元测试_浅谈Java 中的单元测试

    单元测试编写 Junit 单元测试框架 对于Java语言而言,其单元测试框架,有Junit和TestNG这两种, 下面是一个典型的JUnit测试类的结构 package com.example.dem ...

  4. java编程double相乘_浅谈Java double 相乘的结果偏差小问题

    看下面的一段代码的运行结果: public class TestDouble { public static void main(String[] args) { double d =538.8; S ...

  5. java dao service实例_浅谈Action+Service +Dao 功能

    1. Action/Service/DAO简介: Action是管理业务(Service)调度和管理跳转的. Service是管理具体的功能的. Action只负责管理,而Service负责实施. D ...

  6. java变量命名规则_浅谈JAVA开发规范与开发细节(上)

    开发团队在开发过程中,由于每个人的开发习惯,以及对于技术的理解深浅程度不一,往往一个项目在开发过程中,代码的质量,代码的风格都不尽相似,所以有一份适合团队的代码规范是非常有必要的,而一个团队的代码规范 ...

  7. java布尔类型比较器_浅谈Java中几种常见的比较器的实现方法

    在java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题. 通常对象之间的比较可以从两个方面去看: 第一个方面:对象的地址是否一样,也就是是否引用自同一个对象.这种方式可以直接使用& ...

  8. java中定义byte数组,浅谈java的byte数组的不同写法

    (由于篇幅原因阐述的不够详细科学,不喜勿喷). 经常看到java中对byte数组的不同定义,粗略整理的一下: 一个字节(byte)=8位(bit),"byte数组"里面全部是&qu ...

  9. java null什么意思_浅谈java中null是什么,以及使用中要注意的事项

    1.null既不是对象也不是一种类型,它仅是一种特殊的值,你可以将其赋予任何引用类型,你也可以将null转化成任何类型,例如: Integer i=null; Float f=null; String ...

最新文章

  1. spring与memcache的集成
  2. WebGL之sprite精灵效果显式数字贴图
  3. JSONUtils.toJSONString的一个坑
  4. java servlet是接口_JavaWeb:Servlet 接口
  5. js中call与apply用法
  6. SiameseFC超详解
  7. bb10系统支持java吗_黑莓BB10怎么样 BlackBerry 10系统好用吗?
  8. html表格添加选项代码,使用实例演示 表单 中的选项卡功能 在里面添加table id=bootstrap-table/table后不显示表格...
  9. 关于 php 用webservice传输数据的问题(nosoap与.NET对接)此处一直困扰三天时间,终于解决...
  10. 回文绝对求下联:亚冠决赛决冠亚
  11. hdu_5691_Sitting in Line(状压DP)
  12. MFC截图工具(不断更新)
  13. 20190301 小中大
  14. 百度senta使用方法
  15. 使用Apache架设代理服务器
  16. 闲鱼前端组件库的建设
  17. 华为p4支持鸿蒙功能吗_华为鸿蒙2.0系统支持的手机型号 华为鸿蒙2.0系统详解[多图]...
  18. 漫画:什么是 “黑天鹅事件” ?
  19. Git与Git可视化工具TortoiseGit-小乌龟安装和配置
  20. 【经典密码】移位密码和代换密码的实现

热门文章

  1. 密歇根大学张阳团队开发全球首个蛋白质和RNA分子通用结构比对算法
  2. 疯狂来往android版,疯狂来往下载app
  3. layui 重置checkbox全部选中和未选中
  4. Virtual Box 报错,无法为虚拟电脑xxxx创建一个新任务
  5. Lightly 在线编译
  6. win10资源管理器频繁重启可能原因及解决方案——基于日志内容的查找
  7. svg 动画_30个很棒的SVG动画
  8. 机器学习在网络安全领域的应用(一)
  9. Java 编写程序打印以下图形_怎么用java编写如下程序在屏幕上输出如下图形 * *** *** * 循环语句做(if语句)...
  10. 2019.11.4 英语学习