Java 按属性合并列表中对象的实例
我有一个对象人,它有名字、姓氏和电子邮件Java 按属性合并列表中对象的实例,java,collections,java-stream,Java,Collections,Java Stream,我有一个对象人,它有名字、姓氏和电子邮件 班级人员{ 字符串名; 字符串lastName; 字符串电子邮件; } 我有一个人的列表,其中可能有多个人具有相同的firstName和lastName,我想通过他们的电子邮件地址用分隔符合并这些人 i、 e。 人A= { “名字”:“大卫”, “姓氏”:“吉尼”, “电子邮件”:“大卫。guiney@gmail.com" } B人= { “名字”:“大卫”, “姓氏”:“吉尼”, “电子邮件”:“guiney。david@hotmail.com"
班级人员{
字符串名;
字符串lastName;
字符串电子邮件;
}
我有一个人
的列表,其中可能有多个人
具有相同的firstName
和lastName
,我想通过他们的电子邮件地址用分隔符合并这些人
i、 e。
人A=
{
“名字”:“大卫”,
“姓氏”:“吉尼”,
“电子邮件”:“大卫。guiney@gmail.com"
}
B人=
{
“名字”:“大卫”,
“姓氏”:“吉尼”,
“电子邮件”:“guiney。david@hotmail.com"
}
我想把这些合并到
{
“名字”:“大卫”,
“姓氏”:“吉尼”,
“电子邮件”:“大卫。guiney@gmail.com;吉尼。david@hotmail.com"
}
以便在我的列表中创建一个唯一的实例
stringfirstname;
字符串lastName;
字符串电子邮件;
@凌驾
公共布尔等于(对象o)
{
if(this==o)
{
返回true;
}
如果(o==null | | getClass()!=o.getClass())
{
返回false;
}
人=(人)o;
返回Objects.equals(firstname,person.firstname)和&Objects.equals(lastName,person.lastName);
}
@凌驾
公共int hashCode()
{
返回Objects.hash(firstname,lastName);
}
@凌驾
公共字符串toString()
{
返回“Person{”+
“firstname=”+firstname+“\”+
“,lastName='”+lastName+'\''+
“,email='”+email+'\''+
'}';
}
公共静态void main(字符串[]args)
{
List persons=array.asList(新人物(“大卫”、“吉尼”、“大卫”)。guiney@gmail.com"),
新人(“大卫”、“吉尼”、“大卫”。guiney@gmail.com"),
新人(“安德烈亚斯”,“拉达尔”,“请_no@spam.com")
);
独一无二的人=
人流()
.collect(collector.toMap)(
Person::hashCode,
Function.identity(),
(人1,人2)->{
person1.email=person1.email+“;”+person2.email;//这可以改进
返回人员1;
}
));
System.out.println(uniquePersons.values());
}
}
如果您不想在这个用例中使用equals和hashCode,您当然可以只提供自己的getKey逻辑,您可以逐个检查列表中的所有对象,但问题是时间复杂性。它将采用O(n^2)格式
for(int i=0;i首先,如果个人可以有多封电子邮件,我会在Person类中通过一个“emails”属性存储电子邮件集合来反映这一点
然后可以使用Java8流
public class Person {
private String firstName;
private String lastName;
private List<String> emails;// if a person is susceptible to have several emails, use a collection and not a single String
public Person(String firstName, String lastName, String email) {
this.firstName = firstName;
this.lastName = lastName;
this.emails = new ArrayList<>();
this.emails.add(email);
}
public static void main(String[] args) {
List<Person> persons = Arrays.asList(
new Person("David", "Guiney", "david.guiney@gmail.com"),
new Person("Jean", "Patrick", "jp@pluton.com"),
new Person("David", "Guiney", "david.guiney@hotmail.com"),
new Person("Bruce", "Lee", "bl@kungfu.com")
);
// Group together the Person instances having the same firstname and same lastname
Map<List<String>, Person> keyToPerson = persons.stream().collect(Collectors.toMap(
p -> Arrays.asList(p.firstName, p.lastName),// define the key allowing to group person as the combination of firstname and lastname
Function.identity(),// what is associated to the key. Here we want the Person instance itself
(p1, p2) -> {// the logic to solve collision, i.e. instances having the same key
p1.emails.addAll(p2.emails);// add the email(s) of the second instances in the email of the first instance
return p1;
}
));
keyToPerson.values().forEach(p -> {
System.out.println(p.firstName + " " + p.lastName + " (" + String.join("; ", p.emails) + ")");
});
}
您还可以重新定义Person类的equals和hashcode方法,以实现如何将2个实例分组在一起。stream()
和filter()
是您的朋友-请尝试一下,让我们知道我们可以提供哪些帮助。请阅读,四处看看,并通读,特别是如何做和。从第二个链接:“要求家庭作业帮助的问题必须包括到目前为止你为解决问题所做工作的总结,以及对你解决问题的困难的描述。“即使这不是家庭作业。我投票结束这个问题,因为没有尝试。谢谢你,安德烈亚斯,这正是我所需要的。太棒了。谢谢你,在Person对象中使用电子邮件列表将是一个理想的解决方案,但不幸的是,进行更改将破坏许多其他代码。(我正在处理的实际对象是一个更复杂的模型)。上面的第一个响应给出了适合我的理想解决方案。
for(int i=0;i<list.size();i++){
for(int j=i+1;j<list.size();j++){
if(list.get(i).firstName.equals(list.get(j).firstName) && list.get(i).lastName.equals(list.get(j).lastName)){
list.get(i).email += ";"+list.get(j).email;
list.remove(j);
}
}
}
public class Person {
private String firstName;
private String lastName;
private List<String> emails;// if a person is susceptible to have several emails, use a collection and not a single String
public Person(String firstName, String lastName, String email) {
this.firstName = firstName;
this.lastName = lastName;
this.emails = new ArrayList<>();
this.emails.add(email);
}
public static void main(String[] args) {
List<Person> persons = Arrays.asList(
new Person("David", "Guiney", "david.guiney@gmail.com"),
new Person("Jean", "Patrick", "jp@pluton.com"),
new Person("David", "Guiney", "david.guiney@hotmail.com"),
new Person("Bruce", "Lee", "bl@kungfu.com")
);
// Group together the Person instances having the same firstname and same lastname
Map<List<String>, Person> keyToPerson = persons.stream().collect(Collectors.toMap(
p -> Arrays.asList(p.firstName, p.lastName),// define the key allowing to group person as the combination of firstname and lastname
Function.identity(),// what is associated to the key. Here we want the Person instance itself
(p1, p2) -> {// the logic to solve collision, i.e. instances having the same key
p1.emails.addAll(p2.emails);// add the email(s) of the second instances in the email of the first instance
return p1;
}
));
keyToPerson.values().forEach(p -> {
System.out.println(p.firstName + " " + p.lastName + " (" + String.join("; ", p.emails) + ")");
});
}
David Guiney (david.guiney@gmail.com; david.guiney@hotmail.com)
Bruce Lee (bl@kungfu.com)
Jean Patrick (jp@pluton.com)