Java8实战-总结14

news2025/1/11 7:01:50

Java8实战-总结14

  • 引入流
    • 流是什么

引入流

集合是Java中使用最多的API。几乎每个Java应用程序都会制造和处理集合。集合对于很多编程任务来说都是非常基本的:它们可以让数据分组并加以处理。为了解释集合是怎么工作的,想象一下准备列出一系列菜,组成一张菜单,然后再遍历一遍,把每盘菜的热量加起来。可能想选出那些热量比较低的菜,组成一张健康的特殊菜单。尽管集合对于几乎任何一个Java应用都是不可或缺的,但集合操作却远远算不上完美。

  • 很多业务逻辑都涉及类似于数据库的操作,比如对几道菜按照类别进行分组(比如全素菜肴),或查找出最贵的菜。大部分数据库都允许声明式地指定这些操作。比如,以下SQL查询语句就可以选出热量较低的菜肴名称:SELECT name FROM dishes WHERE calorie < 400。你不需要实现如何根据菜肴的属性进行筛选(比如利用迭代器和累加器),只需要表达想要什么。这个基本的思路意味着,用不着担心怎么去显式地实现这些查询语句——都替你办好了,怎么到了集合这里就不能这样了呢?
  • 要是要处理大量元素又该怎么办呢?为了提高性能,需要并行处理,并利用多核架构。但写并行代码比用迭代器还要复杂,而且调试起来也够受的。

Java语言的设计者能做些什么,来帮助你节约宝贵的时间,让程序员活得轻松一点儿呢?答案就是流。

流是什么

流是Java API的新成员,它允许以声明性方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现)。就现在来说,可以把它们看成遍历数据集的高级迭代器。此外,流还可以透明地并行处理,无需写任何多线程代码。简单看看使用流的好处吧。下面两段代码都是用来返回低热量的菜肴名称的,并按照卡路里排序,一个是用Java 7写的,另一个是用Java 8的流写的。

之前(Java 7):

	List<Dish> lowCaloricDishes = new ArrayList<>();
	//用累加器筛选元素
	for(Dish d : menu) {
		if(d.getCalories() < 400){ 
			lowCaloricDishes.add(d);
		}
	}

	//用匿名类对菜肴排序
	Collections.sort(lowCaloricDishes, new Comparator<Dish>() {
		public int compare(Dish d1, Dish d2) {
			return Integer.compare(d1.getcalories(), d2.getcalories());
		}
	});
	
	//处理排序后的菜名列表
	List<String> lowCaloricDishesName = new ArrayList<>();
	for(Dish d : lowCaloricDishes) {
		lowCaloricDishesName.add(d.getName ());
	}

在这段代码中,用了一个“垃圾变量”lowCaloricDishes。它唯一的作用就是作为一次性的中间容器。在Java 8中,实现的细节被放在它本该归属的库里了。之后(Java 8):

import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.toList;
List<String> lowCaloricDishesName =
//选出400卡路里以下的菜肴
				menu.stream()
					.filter(d -> d.getCalories() < 400) //选出400卡路里以下的菜肴
					.sorted(comparing(Dish::getcalories))//按照卡路排序
					.map(Dish::getName)//提取菜肴的名称
					.collect(toList ());//将所有名称保存在List中

为了利用多核架构并行执行这段代码,只需要把stream()换成parallelStream():

List<String> lowCaloricDishesName = menu.parallelstream()
									.filter(d -> d.getcalories() < 400)
									.sorted(comparing(Dishes::getCalories))
									.map(Dish::getName)
									.collect(toList());

在调用parallelStream方法的时候到底发生了什么。用了多少个线程?对性能有多大提升?后续详细讨论这些问题。现在,从软件工程师的角度来看,新的方法有几个显而易见的好处。

代码是以声明性方式写的:说明想要完成什么(筛选热量低的菜肴)而不是说明如何实现一个操作(利用循环和if条件等控制流语句)。这种方法加上行为参数化可以轻松应对变化的需求:很容易再创建一个代码版本,利用Lambda表达式来筛选高卡路里的菜肴,而用不着去复制粘贴代码。

可以把几个基础操作链接起来,来表达复杂的数据处理流水线(在filter后面接上sortedmapcollect操作,如下图所示),同时保持代码清晰可读。filter的结果被传给了sorted方法,再传给map方法,最后传给collect方法。

因为filtersortedmapcollect等操作是与具体线程模型无关的高层次构件,所以它们的内部实现可以是单线程的,也可能透明地充分利用多核架构。在实践中,这意味着用不着为了让某些数据处理任务并行而去操心线程和锁了,Stream API都替你做好了。
在这里插入图片描述
新的Stream API表达能力非常强。比如下面这样的代码:

Map<Dish.Type,List<Dish>> dishesByType = menu.stream().collect(groupingBy(Dish::getType));

简单来说就是,按照Map里面的类别对菜肴进行分组。比如,Map可能包含下列结果:

{FISH = [prawns, salmon],
OTHER = [french fries, rice, season fruit, pizza], MEAT = [pork, beef, chicken]}
其他库:Guava、Apache和lambdaj

为了给Java程序员提供更好的库操作集合,前人已经做过了很多尝试。比如,Guava就是谷歌创建的一个很流行的库。它提供了multimaps和multisets等额外的容器类。
ApacheCommons Collections库也提供了类似的功能。最后,本书作者Mario Fusco编写的lambdaj受到函数式编程的启发,也提供了很多声明性操作集合的工具。

如今Java8自带了官方库,可以以更加声明性的方式操作集合了。

总结一下,Java8中的Stream API可以让你写出这样的代码:

  • 声明性——更简洁,更易读
  • 可复合——更灵活
  • 可并行——性能更好

接下来会用这样一个例子:一个menu,它只是一张菜肴列表。

	List<Dish> menu = Arrays.asList(
				new Dish("pork", false,800, Dish.Type.MEAT),
				new Dish("beef",false,700, Dish.Type.MEAT),
				new Dish("chicken",false,400, Dish.Type.MEAT),
				new Dish("french fries", true, 530, Dish.Type.OTHER),
				new Dish("rice", true,350, Dish.Type.OTHER),
				new Dish("season fruit", true,120, Dish.Type.OTHER),
				new Dish("pizza", true,550, Dish.Type.OTHER),
				new Dish("prawns",false,300, Dish.Type.FISH),
				new Dish("salmon", false, 450, Dish.Type.PISH));

Dish类的定义是:

	public class Dish {
		private final String name;
		private final boolean vegetarian;
		private final int calories;
		private final Type type;
		
		public Dish(String name, boolean vegetarian, int calories, Type type) {
			this.name = name;
			this.vegetarian = vegetarian;
			this.calories = calories;
			this.type = type;
		}
		
		public String getName() {
			return name;
		}
		
		public boolean isVegetarian() {
			return vegetarian;
		}
		
		public int getCalories() {
			return calories;
		}
		
		public Type getType() {
			return type;
		}
		
		@Override
		public String toString(){
			return name;
		}
		
		public enum Type { MEAT,FISH,OTHER }
	}

现在就来仔细探讨一下怎么使用Stream API。会用流与集合做类比,做点儿铺垫。之后会详细讨论可以用来表达复杂数据处理查询的流操作。会谈到很多模式,如筛选、切片、查找、匹配、映射和归约。

接下来,会讨论如何创建和操纵数字流,比如生成一个偶数流,或是勾股数流。最后,会讨论如何从不同的源(比如文件)创建流。还会讨论如何生成一个具有无穷多元素的流——这用集合肯定搞不定。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/851083.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

带你认识红黑树

红黑树 一、什么是红黑树&#xff1f;1.1 AVL树1.2 红黑树 二、红黑树的特点三、红黑树的insert、delete3.1 insert3.1.1 父节点为空3.1.2 父节点为Black节点3.1.3 父节点为Red节点3.1.3.1 叔叔节点为Red节点3.1.3.2 叔叔节点为Black节点 3.2 delete3.2.1 删除节点有两个子节点…

libmpv使用滤镜处理视频进行播放

一、前言 作为一个功能强大的多媒体框架,libmpv为开发者提供了广泛的功能和灵活的控制权。滤镜是libmpv的一个重要特性,允许开发者对视频进行各种实时处理和增强,从而满足用户对于个性化、创意化和高质量视频体验的需求。 滤镜是一种在视频渲染过程中应用特定效果的技术。…

若依-plus-vue启动显示Redis连接错误

用的Redis是windows版本&#xff0c;6.2.6 报错的主要信息如下&#xff1a; Failed to instantiate [org.redisson.api.RedissonClient]: Factory method redisson threw exception; nested exception is org.redisson.client.RedisConnectionException: Unable to connect t…

Vscode-工具使用

Vscode &#xff0c;这玩意儿是开源的&#xff0c;以前用收费的破解版&#xff0c;过段时间就高版本不匹配&#xff0c;这次搞个不要钱的玩玩&#xff0c;记录使用心得 下载 下载地址&#xff1a;官网 点击下载&#xff0c;但是这里有个问题下载比较慢&#xff0c;解决办法&a…

Redhat Linux 安装MySQL安装手册

Redhat安装MySQL安装手册 1 下载2 上传服务器、解压并安装3 安装安装过程1&#xff1a;MySQL-shared-5.6.51-1.el7.x86_64.rpm安装过程2&#xff1a;MySQL-shared-compat-5.6.51-1.el7.x86_64.rpm安装过程3&#xff1a;MySQL-server-5.6.51-1.el7.x86_64.rpm安装过程4&#xff…

从碎片化到整体性,医美服务的下一个战场

近年来&#xff0c;医美消费需求蓬勃增长&#xff0c;各类医美机构、医美平台如雨后春笋般涌现&#xff0c;为医美消费者提供了更多选择的同时&#xff0c;也赋予了他们更大的权利。据调查&#xff0c;在经历了一次不愉快的体验之后&#xff0c;“换一家”——是绝大多数医美消…

k8s --pod详解

目录 一、Pod基础概念 1、pod简介 2、在Kubrenetes集群中Pod有如下两种使用方式 3、pause容器使得Pod中的所有容器可以共享两种资源&#xff1a;网络和存储。 &#xff08;1&#xff09;网络 &#xff08;2&#xff09;存储 4、kubernetes中的pause容器主要为每个容器提供…

IELTS图表类作文基础知识

表格可以用table或chart来表示。 其实&#xff0c;数据类图表除了可以用chart表示&#xff0c;也可以用其他单词。 表格又可以称为table。而带有几何图形的图表可以用graph来表示。 像饼状图、折线图、柱状图这样用几何图形&#xff0c;或者直接用表格来呈现数据的形式&#x…

macOS(m芯片)连接服务器及其进行文件传输的各种方式的详解

说明&#xff1a;使用了macOS后发现&#xff0c;win系统能使用的xshell、xftp等连接服务器及其文件传输等软件均不能使用了&#xff0c;没有兼容的版本。所以我们刚切换到mac系统该如何去适应呢。 一、连接远程服务器 macOS中前文也说道我们使用的是iterm2进行终端控制的&…

【高级程序设计语言C++】红黑树

1. 红黑树的概念2. 红黑树的插入2.1. 情况12.2. 情况22.3. 情况32.4. 插入情况小总结 3. 红黑树与AVL树的对比4. 红黑树在线生成网站 1. 红黑树的概念 红黑树&#xff08;Red-Black Tree&#xff09;是一种自平衡的二叉搜索树&#xff0c;它在插入和删除操作时通过调整节点的颜…

anylabeling安装与使用说明

文章目录 一.anylabeling说明二. 安装教程1. 可执行程序方式2. python程序 一.anylabeling说明 官网:https://anylabeling.nrl.ai/docs 该工具作为一个具有Segment Anything和YOLO模型的智能标签工具&#xff0c;可以快速、准确地对图像进行标注。 二. 安装教程 1. 可执行程…

Docker Desktop 启用 Kubernetes 失败后处理

一、环境 Windows 10 C:\Users\zhuji>docker --version Docker version 24.0.2, build cb74dfc 二、问题 在setting -> Kubernetes 中&#xff0c;选中 Enable Kubernetes 后&#xff0c;长时间显示 Starting ... &#xff0c;在Images中显示几个自动下载的镜像后&…

e6zzseo:外贸独立站怎么推广

外贸独立站的推广需要一系列综合性的策略和方法&#xff0c;以吸引目标市场的访问者&#xff0c;并将他们转化为潜在客户。以下是一些推广外贸独立站的建议&#xff1a; 1. 搜索引擎优化&#xff08;SEO&#xff09;&#xff1a; e6zzseo认为优化网站可以适应搜索引擎的要求&a…

1749. 任意子数组和的绝对值的最大值

诸神缄默不语-个人CSDN博文目录 力扣刷题笔记 文章目录 1. 暴力搜索2. 动态规划3. 前缀和 1. 暴力搜索 直接用2个指针从索引0开始找到最后一个索引&#xff0c;时间复杂度大概是 O ( n 2 ) O(n^2) O(n2)吧&#xff0c;总之这么搞不行&#xff0c;以下是我用Python写的一些典型…

【2.1】Java微服务: Nacos注册中心

目录 Nacos介绍 Nacos安装 下载和安装 修改端口 启动 服务注册与发现 导入Nacos管理依赖 导入服务依赖 配置Nacos的服务地址 启动服务&#xff0c;查看已注册的服务 服务分级存储模型 分级存储模型介绍 具体结构 配置实例集群 同集群优先的负载均衡策略 服务权重配置…

vue中vuex的五个属性和基本用法,另加js-cookie的使用

VueX 是一个专门为 Vue.js 应用设计的状态管理构架&#xff0c;统一管理和维护各个vue组件的可变化状态(你可以理解成 vue 组件里的某些 data )。 Vuex有五个核心概念&#xff1a; state, getters, mutations, actions, modules。 1. state&#xff1a; vuex的基本数据&…

【力扣刷题 | 第二十五天】

目录 前言&#xff1a; 474. 一和零 - 力扣&#xff08;LeetCode&#xff09; 总结: 前言&#xff1a; 今天我们依旧暴打动态规划 474. 一和零 - 力扣&#xff08;LeetCode&#xff09; 给你一个二进制字符串数组 strs 和两个整数 m 和 n 。 请你找出并返回 strs 的最大子集…

docker下载和案例

文章目录 Docker安装一,根据官方文档安装二,根据我以下方式 Docker配置错误导致漏洞一,CRLF注入漏洞介绍在nginx中该漏洞例子解决方法 目录穿越漏洞介绍解决方法 Docker安装 一,根据官方文档安装 官方文档 二,根据我以下方式 docker安装要求&#xff1a; Docker要求Ce…

Unity游戏源码分享-植物大战僵尸素材与源码

Unity游戏源码分享-植物大战僵尸素材与源码 完整版本下载地址&#xff1a; https://download.csdn.net/download/Highning0007/88191862

【Windbg】通过网络调试windows内核

环境 windows版本&#xff1a;win10_x64 1901 windbg版本&#xff1a;1.2306.12001.0 HOST 1、windbg软件设置。 点击菜单文件&#xff0c;然后如下图操作。 2、等待连接。 ************* Waiting for Debugger Extensions Gallery to Initialize **************>>&…