【Java 8】Stream.distinct() 列表去重示例
在这篇文章里,我们将提供Java8 Stream distinct()示例。
distinct()返回由该流的不同元素组成的流。distinct()是Stream接口的方法。
distinct()使用hashCode()和equals()方法来获取不同的元素。因此,我们的类必须实现hashCode()和equals()方法。
如果distinct()正在处理有序流,那么对于重复元素,将保留以遭遇顺序首先出现的元素,并且以这种方式选择不同元素是稳定的。在无序流的情况下,不同元素的选择不一定是稳定的,是可以改变的。distinct()执行有状态的中间操作。在有序流的并行流的情况下,保持distinct()的稳定性是需要很高的代价的,因为它需要大量的缓冲开销。如果我们不需要保持遭遇顺序的一致性,那么我们应该可以使用通过BaseStream.unordered()方法实现的无序流。
Stream.distinct()
distinct()方法的声明如下:
Stream<T> distinct()
它是Stream接口的方法。在此示例中,我们有一个包含重复元素的字符串数据类型列表
DistinctSimpleDemo.java
package com.concretepage;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class DistinctSimpleDemo {
public static void main(String[] args) {
List<String> list = Arrays.asList("AA", "BB", "CC", "BB", "CC", "AA", "AA");
long l = list.stream().distinct().count();
System.out.println("No. of distinct elements:"+l);
String output = list.stream().distinct().collect(Collectors.joining(","));
System.out.println(output);
}
}
Output
No. of distinct elements:3
AA,BB,CC
Stream.distinct() with List of Objects
在此示例中,我们有一个Book对象列表。 为了对列表进行去重,该类将重写hashCode()和equals()。
Book.java
package com.concretepage;
public class Book {
private String name;
private int price;
public Book(String name, int price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public int getPrice() {
return price;
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
final Book book = (Book) obj;
if (this == book) {
return true;
} else {
return (this.name.equals(book.name) && this.price == book.price);
}
}
@Override
public int hashCode() {
int hashno = 7;
hashno = 13 * hashno + (name == null ? 0 : name.hashCode());
return hashno;
}
}
DistinctWithUserObjects.java
package com.concretepage;
import java.util.ArrayList;
import java.util.List;
public class DistinctWithUserObjects {
public static void main(String[] args) {
List<Book> list = new ArrayList<>();
{
list.add(new Book("Core Java", 200));
list.add(new Book("Core Java", 200));
list.add(new Book("Learning Freemarker", 150));
list.add(new Book("Spring MVC", 300));
list.add(new Book("Spring MVC", 300));
}
long l = list.stream().distinct().count();
System.out.println("No. of distinct books:"+l);
list.stream().distinct().forEach(b -> System.out.println(b.getName()+ "," + b.getPrice()));
}
}
Output
No. of distinct books:3
Core Java,200
Learning Freemarker,150
Spring MVC,300
Distinct by Property
distinct()不提供按照属性对对象列表进行去重的直接实现。它是基于hashCode()和equals()工作的。如果我们想要按照对象的属性,对对象列表进行去重,我们可以通过其它方法来实现。如下代码段所示:
static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Map<Object,Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
上面的方法可以被Stream接口的 filter()接收为参数,如下所示:
list.stream().filter(distinctByKey(b -> b.getName()));
distinctByKey()方法返回一个使用ConcurrentHashMap 来维护先前所见状态的 Predicate 实例,如下是一个完整的使用对象属性来进行去重的示例。
DistinctByProperty.java
package com.concretepage;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
public class DistinctByProperty {
public static void main(String[] args) {
List<Book> list = new ArrayList<>();
{
list.add(new Book("Core Java", 200));
list.add(new Book("Core Java", 300));
list.add(new Book("Learning Freemarker", 150));
list.add(new Book("Spring MVC", 200));
list.add(new Book("Hibernate", 300));
}
list.stream().filter(distinctByKey(b -> b.getName()))
.forEach(b -> System.out.println(b.getName()+ "," + b.getPrice()));
}
private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
Map<Object,Boolean> seen = new ConcurrentHashMap<>();
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}
}
Output
Core Java,200
Learning Freemarker,150
Spring MVC,200
Hibernate,300
from : https://www.concretepage.com/java/jdk-8/java-8-distinct-example
【Java 8】Stream.distinct() 列表去重示例的更多相关文章
- Java 8 Stream API的使用示例
前言 Java Stream API借助于Lambda表达式,为Collection操作提供了一个新的选择.如果使用得当,可以极大地提高编程效率和代码可读性. 本文将介绍Stream API包含的方法 ...
- java中List对象列表去重或取出以及排序
面试碰到几次list的去重和排序.下面介绍一种做法: 1. list去重 1.1 实体类Student List<Student>容量10k以上,要求去重复.这里Student的重复标准是 ...
- Stream API的代码示例.md
一.代码实例: package com.TestMain; import com.alibaba.fastjson.JSON; import java.util.*; import java.util ...
- java 8 stream、lambda表达式对list操作分组、过滤、求和、最值、排序、去重
1.分组 通过groupingBy分组指定字段 list.stream().collect(Collectors.groupingBy(User::getSex)); 2.过滤 通过filter方法过 ...
- Java 8 stream 经典示例
package org.study2.java8.stream; import org.junit.Test; import java.util.*; import java.util.stream. ...
- Java 8 Lambda表达式10个示例【存】
PS:不能完全参考文章的代码,请参考这个文件http://files.cnblogs.com/files/AIThink/Test01.zip 在Java 8之前,如果想将行为传入函数,仅有的选择就是 ...
- 关于java中Stream理解
关于java中Stream理解 Stream是什么 Stream:Java 8新增的接口,Stream可以认为是一个高级版本的Iterator.它代表着数据流,流中的数据元素的数量可以是有限的, 也可 ...
- Java 8 Stream实践
[**前面的话**]Java中的Stream于1.8版本析出,平时项目中也有用到,今天就系统的来实践一下.下面借用重庆力帆队伍中我个人比较喜欢的球员来操作一波,队员的年龄为了便于展示某些api做了调整 ...
- [零]java8 函数式编程入门官方文档中文版 java.util.stream 中文版 流处理的相关概念
前言 本文为java.util.stream 包文档的译文 极其个别部分可能为了更好理解,陈述略有改动,与原文几乎一致 原文可参考在线API文档 https://docs.oracle.com/jav ...
随机推荐
- 解决虚拟机安装linux系统无法全屏问题 & vmtools安装
修改设置 1) 如下图右单击虚拟机名,选择[settings-],调出虚拟机设置界面. 2) 在设置界面选择[hardware]->[CD/DVD2(IDE)]->[Connection] ...
- vs Code配置C++运行和调试环境以及相关问题
vs Code配置C++运行和调试环境以及相关问题 第一步:下载c++插件 第二步:安装编译.调试环境 如果没有Dev-C++下载MinGW 下载地址:https://sourceforge.net/ ...
- Linux mem 2.4 Buddy 内存管理机制
文章目录 1. Buddy 简介 2. Buddy 初始化 2.1 Struct Page 初始化 2.2 Buddy 初始化 3. 内存释放 4. 内存分配 4.1 gfp_mask 4.2 nod ...
- MAC电脑如何将常规视频中音频提取出来(转换格式并调整采样频率),并利用讯飞语音识别文字
1.下载好相关视频 2.选中需要提取视频,鼠标右键找到「编码所选视频文件」 3.设置中,下拉选择「仅音频」,点击继续 4.找到已提取成功的音频,鼠标右键或快捷键「command + I」,显示简介.默 ...
- Part 1 to 10 Basic in C#
Part 1 Introduction The struct of C# program: namespace , class and Main method what is namespace? t ...
- 菜鸡的Java笔记 第五 - java 程序逻辑控制
程序主要分为三种逻辑:顺序,分支,循环. if 分支语句 if分支语句是最为基础的分支操作,但是其有三种使用形式: if语句 if.....else 语句 if....else...if...el ...
- JDBC操作多张表一
一.操作一对多情况开发步骤1创建对象 //代码部门的对象public class Department { private String id; private String name; privat ...
- 数字逻辑实践3->EDA技术与Verilog设计
本文属于EDA技术概述类文章 1 EDA技术及其发展 概念 EDA(Electronic Design Automation),指的是以计算机为工作平台,以EDA软件工具为开发环境,以PLD期间或者A ...
- idea内存配置
找到IDEA安装的bin目录 打开idea.exe.vmoptions 文件 如果嫌麻烦还打开了idea 那么就可以点击这个.. 关键的三个参数的说明 1. -Xms 是最小启动内存参数 2. -X ...
- tomcat进行远程debug
Windows下 进入目录下的bin目录,编辑打开startup.bat 在前面添加: SET CATALINA_OPTS=-server -Xdebug -Xnoagent -Djava.com ...