Java 8 Stream 中的属性不同
本文通过属性演示了在 Java 中使用流的独特功能。
Java 8 Stream 中的属性不同
Java 8 Stream 有一个 distinct()
方法,可以过滤列表中的重复项。 此方法使用实例中的 equal 方法来检查唯一元素,如果发现重复项,则将其删除。
如果需要将 distinct()
方法应用于某个属性或字段,我们就不能使用它。 但是我们可以使用特定的方式按属性应用 distinct()
方法。
让我们尝试一个例子,我们创建一个 Employee 类,其中包含员工的姓名和 id,然后尝试在 Employee 类列表的流中使用 unique()
方法:
package jiyik;
import java.util.List;
import java.util.Objects;
class Employee {
private String Employee_Name;
private int Employee_ID;
public Employee(String Employee_Name, int Employee_ID) {
this.Employee_Name = Employee_Name;
this.Employee_ID = Employee_ID;
}
public String getName() {
return Employee_Name;
}
public int getID() {
return Employee_ID;
}
@Override
public boolean equals(Object Demo_Object) {
if (this == Demo_Object) {
return true;
}
if (Demo_Object == null) {
return false;
}
if (getClass() != Demo_Object.getClass()) {
return false;
}
Employee other = (Employee) Demo_Object;
return Objects.equals(Employee_Name, other.Employee_Name);
}
@Override
public int hashCode() {
return Objects.hash(Employee_Name);
}
@Override
public String toString() {
return Employee_Name + " " + Employee_ID;
}
}
public class Example {
public static void main(String[] args){
List<Employee> Employee_List = List.of(
new Employee("Sheeraz", 10),
new Employee("John", 20),
new Employee("Sheeraz", 30),
new Employee("Robert", 40),
new Employee("Jake", 50),
new Employee("Logan", 60)
);
//the distinct() will remove the duplicates by equals
Employee_List.stream()
.distinct()
.forEach(System.out::println);
}
}
上面的代码将在使用流的 Employee 类列表上使用 unique()
方法,并删除具有相同值的条目。 代码展示了 distinct()
方法的简单使用。
现在,让我们看看如何在 Java 中按属性应用不同的逻辑。
使用Collectors.toMap在Java中应用Distinct by Property
我们可以使用 Collectors.toMap 将流的元素收集到映射中,以由属性或字段作为键控。 该映射对于一个键只能有一个值,因此我们需要为每个键选择第一个流对象。
我们可以从结果映射中调用 values()
,它应用不同的逻辑并通过我们分组的自定义属性为我们提供唯一的值。 让我们看一个例子:
package jiyik;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
class Employee {
private String Employee_Name;
private int Employee_ID;
public Employee(String Employee_Name, int Employee_ID) {
this.Employee_Name = Employee_Name;
this.Employee_ID = Employee_ID;
}
public String getName() {
return Employee_Name;
}
public int getID() {
return Employee_ID;
}
@Override
public boolean equals(Object Demo_Object) {
if (this == Demo_Object) {
return true;
}
if (Demo_Object == null) {
return false;
}
if (getClass() != Demo_Object.getClass()) {
return false;
}
Employee other = (Employee) Demo_Object;
return Objects.equals(Employee_Name, other.Employee_Name);
}
@Override
public int hashCode() {
return Objects.hash(Employee_Name);
}
@Override
public String toString() {
return Employee_Name + " " + Employee_ID;
}
}
public class Example {
public static void main(String[] args){
List<Employee> Employee_List = List.of(
new Employee("Sheeraz", 10),
new Employee("John", 20),
new Employee("Sheeraz", 30),
new Employee("Robert", 40),
new Employee("Jake", 50),
new Employee("Logan", 60)
);
Collection<Employee> Unique_EmployeeList = Employee_List.stream()
.collect(Collectors.toMap(Employee::getName, Function.identity(),
(Employee1, Employee2) -> Employee1))
.values();
System.out.println(Unique_EmployeeList);
}
}
上面的代码将使用基于 Employee_Name 属性的 Collection.toMap 方法在流上应用不同的逻辑,这意味着代码将返回具有唯一员工姓名的列表。 查看输出:
[Jake 50, Logan 60, Robert 40, John 20, Sheeraz 10]
我们可以看到,Employee 列表中有两个名为 Sheeraz 的条目,其中一个被删除,因为我们根据 name 属性应用了不同的值。
使用包装类在 Java 中应用“按属性区分”
我们还可以创建一个包装类,将属性分配给 Employee 类,然后按包装类中的属性应用distinct() 方法。 包装类将是私有静态的并在驱动程序类中声明。
参见示例:
package jiyik;
import java.util.List;
import java.util.Objects;
class Employee {
private String Employee_Name;
private int Employee_ID;
public Employee(String Employee_Name, int Employee_ID) {
this.Employee_Name = Employee_Name;
this.Employee_ID = Employee_ID;
}
public String getName() {
return Employee_Name;
}
public int getID() {
return Employee_ID;
}
@Override
public boolean equals(Object Demo_Object) {
if (this == Demo_Object) {
return true;
}
if (Demo_Object == null) {
return false;
}
if (getClass() != Demo_Object.getClass()) {
return false;
}
Employee other = (Employee) Demo_Object;
return Objects.equals(Employee_Name, other.Employee_Name);
}
@Override
public int hashCode() {
return Objects.hash(Employee_Name);
}
@Override
public String toString() {
return Employee_Name + " " + Employee_ID;
}
}
public class Example {
private static class EmployeeWrapper {
private Employee Employee;
private EmployeeWrapper(Employee Employee) {
this.Employee = Employee;
}
public Employee getEmployee() {
return Employee;
}
@Override
public boolean equals(Object Demo_Object) {
if (this == Demo_Object) {
return true;
}
if (Demo_Object == null) {
return false;
}
if (getClass() != Demo_Object.getClass()) {
return false;
}
EmployeeWrapper other = (EmployeeWrapper) Demo_Object;
return Objects.equals(Employee.getName(), other.Employee.getName());
}
@Override
public int hashCode() {
return Objects.hash(Employee.getName());
}
}
public static void main(String[] args){
List<Employee> Employee_List = List.of(
new Employee("Sheeraz", 10),
new Employee("John", 20),
new Employee("Sheeraz", 30),
new Employee("Robert", 40),
new Employee("Jake", 50),
new Employee("Logan", 60)
);
Employee_List.stream()
.map(EmployeeWrapper::new)
.distinct()
.map(EmployeeWrapper::getEmployee)
.forEach(System.out::println);
}
}
上面的代码使用包装类 EmployeeWrapper 和流中的 unique()
方法来获取具有唯一名称的员工列表。 我们可以看到,在包装类中,我们在 equals()
方法中分配了属性名称,然后我们在驱动类中使用它。
查看输出:
Sheeraz 10
John 20
Robert 40
Jake 50
Logan 60
使用distinctByKey方法在Java中应用Distinct by Property
在这种方法中,我们必须使用并发哈希映射来查找是否存在具有相同值的现有键。 该方法将在驱动程序类中声明,然后通过 filter()
方法在流中使用。
参见示例:
package jiyik;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
class Employee {
private String Employee_Name;
private int Employee_ID;
public Employee(String Employee_Name, int Employee_ID) {
this.Employee_Name = Employee_Name;
this.Employee_ID = Employee_ID;
}
public String getName() {
return Employee_Name;
}
public int getID() {
return Employee_ID;
}
@Override
public boolean equals(Object Demo_Object) {
if (this == Demo_Object) {
return true;
}
if (Demo_Object == null) {
return false;
}
if (getClass() != Demo_Object.getClass()) {
return false;
}
Employee other = (Employee) Demo_Object;
return Objects.equals(Employee_Name, other.Employee_Name);
}
@Override
public int hashCode() {
return Objects.hash(Employee_Name);
}
@Override
public String toString() {
return Employee_Name + " " + Employee_ID;
}
}
public class Example {
public static <T> Predicate<T> distinctByKey(Function<? super T, Object> Key_Extractor)
{
Map<Object, Boolean> Employee_Map = new ConcurrentHashMap<>();
return t -> Employee_Map.putIfAbsent(Key_Extractor.apply(t), Boolean.TRUE) == null;
}
public static void main(String[] args){
List<Employee> Employee_List = List.of(
new Employee("Sheeraz", 10),
new Employee("John", 20),
new Employee("Sheeraz", 30),
new Employee("Robert", 40),
new Employee("Jake", 50),
new Employee("Logan", 60)
);
// Get distinct objects by one key
List<Employee> Distinct_Employees1 = Employee_List.stream()
.filter( distinctByKey(p -> p.getName() ) )
.collect( Collectors.toList() );
System.out.println( Distinct_Employees1 );
// Get distinct objects by one key
List<Employee> Distinct_Employees2 = Employee_List.stream()
.filter( distinctByKey(p -> p.getName() + " "+ p.getID() ) )
.collect( Collectors.toList() );
System.out.println( Distinct_Employees2 );
}
}
上面的代码尝试根据名称以及名称和 ID 获取不同的元素。 查看输出:
[Sheeraz 10, John 20, Robert 40, Jake 50, Logan 60]
[Sheeraz 10, John 20, Sheeraz 30, Robert 40, Jake 50, Logan 60]
正如我们所看到的,第一个列表仅通过 name 属性来区分,第二个列表通过 name 和 ID 属性来区分。
相关文章
如何在 Java 中延迟几秒钟的时间
发布时间:2023/12/17 浏览次数:217 分类:Java
-
本篇文章主要介绍如何在 Java 中制造程序延迟。本教程介绍了如何在 Java 中制造程序延时,并列举了一些示例代码来了解它。
如何在 Java 中把 Hashmap 转换为 JSON 对象
发布时间:2023/12/17 浏览次数:187 分类:Java
-
它描述了允许我们将哈希图转换为简单的 JSON 对象的方法。本文介绍了在 Java 中把 Hashmap 转换为 JSON 对象的方法。我们将看到关于创建一个 hashmap,然后将其转换为 JSON 对象的详细例子。
如何在 Java 中按值排序 Map
发布时间:2023/12/17 浏览次数:171 分类:Java
-
本文介绍了如何在 Java 中按值对 Map 进行排序。本教程介绍了如何在 Java 中按值对 Map
进行排序,并列出了一些示例代码来理解它。
如何在 Java 中打印 HashMap
发布时间:2023/12/17 浏览次数:192 分类:Java
-
本帖介绍了如何在 Java 中打印 HashMap。本教程介绍了如何在 Java 中打印 HashMap 元素,还列举了一些示例代码来理解这个主题。
在 Java 中更新 Hashmap 的值
发布时间:2023/12/17 浏览次数:146 分类:Java
-
本文介绍了如何在 Java 中更新 HashMap 中的一个值。本文介绍了如何在 Java 中使用 HashMap 类中包含的两个方法-put() 和 replace() 更新 HashMap 中的值。
Java 中的 hashmap 和 map 之间的区别
发布时间:2023/12/17 浏览次数:79 分类:Java
-
本文介绍了 Java 中的 hashmap 和 map 接口之间的区别。本教程介绍了 Java 中 Map 和 HashMap 之间的主要区别。在 Java 中,Map 是用于以键值对存储数据的接口,
在 Java 中获取用户主目录
发布时间:2023/12/17 浏览次数:218 分类:Java
-
这篇文章向你展示了如何在 Java 中获取用户主目录。本教程介绍了如何在 Java 中获取用户主目录,并列出了一些示例代码以指导你完成该主题。
Java 中 size 和 length 的区别
发布时间:2023/12/17 浏览次数:179 分类:Java
-
这篇文章教你如何知道 Java 中大小和长度之间的区别。本教程介绍了 Java 中大小和长度之间的区别。我们还列出了一些示例代码以帮助你理解该主题。
Java 中的互斥锁
发布时间:2023/12/17 浏览次数:111 分类:Java
-
了解有关 Java 中互斥锁的一切,在计算机科学领域,互斥或互斥被称为并发控制的属性。每台计算机都使用称为线程的最小程序指令序列。有一次,计算机在一个线程上工作。为了更好地理解,