[英]Get duplicated items with specific format from Java Stream
I'm new with Java streams and I'm playing around with them right now.我是 Java 流的新手,我现在正在玩它们。 Given that I receive a list of persons I want to detect which of them are duplicated and print them as "{Id1} is duplicated with {Id3}{Id4} and its duplicated values are Name, Lastname, FamilyName and Birthday"
鉴于我收到一个人名单,我想检测哪些人是重复的,并将它们打印为“{Id1} 与 {Id3}{Id4} 重复,其重复值是姓名、姓氏、家庭姓名和生日”
So this is my person class, I have already override the equals method in order to get the duplicated based on my criterias所以这是我的个人类,我已经覆盖了 equals 方法,以便根据我的标准获取重复项
public class Person {
private int id;
private String name;
private String familyName;
private String birthday;
private String city;
public Person(int id, String name, String familyName, String birthday, String city) {
this.id = id;
this.name = name;
this.familyName = familyName;
this.birthday = birthday;
this.city = city;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getFamilyName() {
return familyName;
}
public void setFamilyName(String familyName) {
this.familyName = familyName;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public int hashCode() {
return Objects.hash( name,familyName,birthday,city);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return false;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Person other = (Person) obj;
if (!Objects.equals(name, other.name)) {
return false;
}
if (!Objects.equals(familyName, other.familyName)) {
return false;
}
if (!Objects.equals(birthday, other.birthday)) {
return false;
}
return true;
}
} }
Then, I'm getting the list of duplicates in the following method然后,我在以下方法中获取重复项列表
personList.stream()
.filter(p -> personList.contains(p))
.collect(Collectors.toList()).forEach(p-> {
System.out.println(p.getId() + " " + p.getName() + " " + p.getFamilyName() + " " + p.getBirthday());
});
It prints the following:它打印以下内容:
As you can see ID's 2 and 7 are duplicated and also 4,9 and 11 are duplicated and those ones are the ones that I need to print in that format but I don't know how to do it with streams so far.如您所见,ID 的 2 和 7 是重复的,并且 4,9 和 11 也是重复的,这些是我需要以该格式打印的那些,但到目前为止我不知道如何使用流进行打印。
First of all, you should fix your hashCode()
implementation to match your equals
.首先,您应该修复您的
hashCode()
实现以匹配您的equals
。 If two objects are equal, they must have the same hashCode()
.如果两个对象相等,则它们必须具有相同的
hashCode()
。
Now, your Stream
pipeline returns all elements, since your filter
's Predicate
will always return true
.现在,您的
Stream
管道返回所有元素,因为您的filter
的Predicate
将始终返回true
。
Instead, you can group equal elements of the List
:相反,您可以将
List
相等元素分组:
Map<Person,List<Integer>> grouped =
personList.stream()
.collect(Collectors.groupingBy(Function.identity(),
Collectors.mapping(Person::getId,
Collectors.toList())));
Now, for each Person
, you have an associated List
of identifiers.现在,对于每个
Person
,您都有一个关联的标识符List
。 You can iterate this Map
and print the Person
s having List
s with size > 1.您可以迭代此
Map
并打印具有大小 > 1 的List
的Person
。
For example:例如:
personList.stream()
.collect(Collectors.groupingBy(Function.identity(),
Collectors.mapping(Person::getId,
Collectors.toList())));
.entrySet()
.stream()
.filter(e -> e.getValue().size() > 1)
.forEach(e -> System.out.println(e.getKey().getId() + " " + e.getKey().getName() + " " + e.getKey().getFamilyName() + " " + e.getKey().getBirthday() + " " + e.getValue()));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.