我有一系列的人,有吸引人的名字和薪水。
ArrayList<Person> persons = new ArrayList<>();
现在我需要在数组中找到相同的名称,如果是这样的话,将一个薪水相互添加并删除它的副本。
我试过这个
for(Persons per : persons) {
if(per.getName().equals(per.getName()))
{
per.setSalary(per.getSalary()+per.getSalary())
persons.remove(per)
}
}
但它显然不起作用。 我该怎么办?
答案 0 :(得分:1)
你在getName和getSalary上忘了()。
答案 1 :(得分:0)
您只是比较相同的数组元素。您需要使用两个嵌套循环来执行此操作。
答案 2 :(得分:0)
不要忘记致电persons.remove(per)
的人应该ConcurrentModificationException
。
您需要迭代列表Iterator personsIter = persons.iterator()
,然后personsIter.remove(per)
答案 3 :(得分:0)
您可以在以下示例中创建另一个列表(retainedPersons
),使用它尚未包含的Person
对象填充它,如果Person
对象已经存在,则更新工资那里。
ArrayList<Person> persons = new ArrayList<>();
ArrayList<Person> retainedPersons = new ArrayList<>();
for (Person per : persons) {
int personsIndex = retainedPersons.indexOf(per);
// Person found, update salary
if (personsIndex > -1) {
Person retainedPerson = retainedPersons.get(personsIndex);
retainedPerson.setSalary(retainedPerson.getSalary() + per.getSalary());
} else {
// Person not found, add it
retainedPersons.add(per);
}
}
请注意,要使indexOf
正常工作,您的Person
对象必须覆盖equals
方法,以便将两个具有相同名称的人视为相同。例如:
public class Person {
private double salary;
private String name;
public double getSalary() {
return salary;
}
public void setSalary(final double salary) {
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Person other = (Person) obj;
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
return true;
}
}
答案 4 :(得分:0)
如果您使用的是Java 8,则可以使用Stream API:
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.junit.Test;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.reducing;
@Data
@NoArgsConstructor
@AllArgsConstructor
class Person {
private String name = "";
private Double salary = 0.0;
}
public class PersonTest {
@Test
public void test() {
List<Person> persons = Arrays.asList(
new Person("John", 2.0),
new Person("Mary", 2.4),
new Person("John", 4.0));
System.out.println(persons);
Collection<Person> filteredPersons = persons.stream()
.collect(groupingBy(Person::getName, reducing(new Person(), (p1, p2) -> new Person(p2.getName(), p1.getSalary() + p2.getSalary()))))
.values();
System.out.println(filteredPersons);
}
}
输出:
[Person(name=John, salary=2.0), Person(name=Mary, salary=2.4), Person(name=John, salary=4.0)]
[Person(name=John, salary=6.0), Person(name=Mary, salary=2.4)]
答案 5 :(得分:0)
这个很棘手。 首先必须遍历每个实例并将其与除自身之外的每个实例进行比较。 接下来,您必须在迭代时从列表中删除某些内容。
在这里,我有一个简单的for循环(在ArrayList等情况下可以使用,但是在类似LinkedList的情况下,你必须有一个不同的迭代器)
在循环中,我遍历列表中的其余元素并检查它们是否是不同的对象实例,但具有相同的名称。 如果确实如此,则该人员将从列表中删除。
balancer://
我认为这是最容易阅读的,它不会改变对象引用:D
答案 6 :(得分:0)
ArrayList<Person> outputList = new ArrayList<Person>();
// grouping persons by name
Map<String, List<Person>> mapofPersonByName = persons.stream().collect(Collectors.groupingBy(new Function<Person, String>() {
@Override
public String apply(Person t) {
// TODO Auto-generated method stub
return t.getName();
}
}));
mapofPersonByName.entrySet().forEach(entry -> {
String name = entry.getKey();
List<Person> duplicatePersons = entry.getValue();
double salary = duplicatePersons.stream().mapToDouble(person -> person.getSalary()).sum();
Person personobj = new Person(name, salary);
outputList.add(personobj);
});
System.out.println(outputList);