按属性合并列表中的对象实例
Merging instances of objects in a list by attribute
我有一个对象 Person,它有 firstName、lastName 和 email
class Person {
String firstname;
String lastName;
String email;
}
我有一个 Person
的列表,其中可能有多个 Persons
相同的 firstName
和 lastName
我想通过他们的电子邮件地址将它们合并一个分隔符。
即
人 A =
{
"firstName": "David",
"lastName": "Guiney",
"email": "david.guiney@gmail.com"
}
B =
{
"firstName": "David",
"lastName": "Guiney",
"email": "guiney.david@hotmail.com"
}
我希望将这些合并到
{
"firstName": "David",
"lastName": "Guiney",
"email": "david.guiney@gmail.com;guiney.david@hotmail.com"
}
以便在我的列表中创建一个唯一的实例。
这取决于您将什么定义为唯一或相等。这可以通过 equals 和 hashCode 方法来表达。
您可以使用 java.util.stream.Collectors#toMap 方法提供合并功能并将您的列表映射到地图。在合并功能中,您可以实现应如何处理具有相同“键”的 2 个对象的逻辑。
public class 人
{
public 人(字符串名字,字符串姓氏,字符串电子邮件)
{
this.firstname = 名字;
this.lastName = 姓氏;
this.email = 电子邮件;
}
String firstname;
String lastName;
String email;
@Override
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (o == null || getClass() != o.getClass())
{
return false;
}
Person person = (Person) o;
return Objects.equals(firstname, person.firstname) && Objects.equals(lastName, person.lastName);
}
@Override
public int hashCode()
{
return Objects.hash(firstname, lastName);
}
@Override
public String toString()
{
return "Person{" +
"firstname='" + firstname + '\'' +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
'}';
}
public static void main(String[] args)
{
List<Person> persons = Arrays.asList(new Person("David", "Guiney", "david.guiney@gmail.com"),
new Person("David", "Guiney", "david.guiney@gmail.com"),
new Person("Andreas", "Radauer", "please_no@spam.com")
);
Map<Integer, Person> uniquePersons =
persons.stream()
.collect(Collectors.toMap(
Person::hashCode,
Function.identity(),
(person1, person2) -> {
person1.email = person1.email + ";" + person2.email; // this could be improved
return person1;
}
));
System.out.println(uniquePersons.values());
}
}
如果您不想为此用例使用 equals 和 hashCode,您当然可以提供自己的 getKey 逻辑
您可以将列表中的所有对象一一检查,但问题是时间复杂度。它将采用 O(n^2).
形式
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);
}
}
}
首先,如果一个人可以拥有多封电子邮件,我会在 Person class 中反映这一点,方法是让“电子邮件”属性存储电子邮件集合。
然后你可以使用Java 8个流。
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)
您还可以重新定义 Person 的 equals 和 hashcode 方法 class 来实现如何将 2 个实例组合在一起。
我有一个对象 Person,它有 firstName、lastName 和 email
class Person {
String firstname;
String lastName;
String email;
}
我有一个 Person
的列表,其中可能有多个 Persons
相同的 firstName
和 lastName
我想通过他们的电子邮件地址将它们合并一个分隔符。
即 人 A =
{
"firstName": "David",
"lastName": "Guiney",
"email": "david.guiney@gmail.com"
}
B =
{
"firstName": "David",
"lastName": "Guiney",
"email": "guiney.david@hotmail.com"
}
我希望将这些合并到
{
"firstName": "David",
"lastName": "Guiney",
"email": "david.guiney@gmail.com;guiney.david@hotmail.com"
}
以便在我的列表中创建一个唯一的实例。
这取决于您将什么定义为唯一或相等。这可以通过 equals 和 hashCode 方法来表达。
您可以使用 java.util.stream.Collectors#toMap 方法提供合并功能并将您的列表映射到地图。在合并功能中,您可以实现应如何处理具有相同“键”的 2 个对象的逻辑。
public class 人 { public 人(字符串名字,字符串姓氏,字符串电子邮件) { this.firstname = 名字; this.lastName = 姓氏; this.email = 电子邮件; }
String firstname; String lastName; String email; @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } Person person = (Person) o; return Objects.equals(firstname, person.firstname) && Objects.equals(lastName, person.lastName); } @Override public int hashCode() { return Objects.hash(firstname, lastName); } @Override public String toString() { return "Person{" + "firstname='" + firstname + '\'' + ", lastName='" + lastName + '\'' + ", email='" + email + '\'' + '}'; } public static void main(String[] args) { List<Person> persons = Arrays.asList(new Person("David", "Guiney", "david.guiney@gmail.com"), new Person("David", "Guiney", "david.guiney@gmail.com"), new Person("Andreas", "Radauer", "please_no@spam.com") ); Map<Integer, Person> uniquePersons = persons.stream() .collect(Collectors.toMap( Person::hashCode, Function.identity(), (person1, person2) -> { person1.email = person1.email + ";" + person2.email; // this could be improved return person1; } )); System.out.println(uniquePersons.values()); }
}
如果您不想为此用例使用 equals 和 hashCode,您当然可以提供自己的 getKey 逻辑
您可以将列表中的所有对象一一检查,但问题是时间复杂度。它将采用 O(n^2).
形式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);
}
}
}
首先,如果一个人可以拥有多封电子邮件,我会在 Person class 中反映这一点,方法是让“电子邮件”属性存储电子邮件集合。
然后你可以使用Java 8个流。
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)
您还可以重新定义 Person 的 equals 和 hashcode 方法 class 来实现如何将 2 个实例组合在一起。