Reputation: 3
I have an array of Persons, with getters and setters of name and salaries.
ArrayList<Person> persons = new ArrayList<>();
Now i need to find equal names in an array and if it so, add one salary to one another and remove duplicate of it.
i've tried this
for(Persons per : persons) {
if(per.getName().equals(per.getName()))
{
per.setSalary(per.getSalary()+per.getSalary())
persons.remove(per)
}
}
But it obviously doesn't work. How can i do it?
Upvotes: 0
Views: 148
Reputation: 57
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);
Upvotes: 0
Reputation: 1071
This one is tricky. You first have to loop over each instance and compare it to every instance except itself. Next to which, you have to remove something from a list while iterating over it.
Here, I have a simple for loop (which would work in cases such as an ArrayList, but in case of something like a LinkedList, you have to have a different iterator)
In the loop, I iterate over the remaining elements in the list and check if they are different object instances, but have the same name. If that is true, the person is removed from the list.
for (int i = 0; i < persons.size(); i++)
{
Person per1 = persons.get(i);
for (ListIterator<Person> iter = persons.listIterator(i); iter.hasNext(); )
{
Person per2 = iter.next();
if (per1 != per2 &&
per1.getName().equals(per2.getName()))
{
per1.setSalary(per1.getSalary() + per2.getSalary());
iter.remove();
}
}
}
I suppose this is the easiest to read, and it doesnt change the object references :D
Upvotes: 0
Reputation: 2276
If you are using Java 8 you can make it using 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);
}
}
Output:
[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)]
Upvotes: 0
Reputation: 17524
You may create another list (retainedPersons
in the following example), populate it with Person
objects it doesn't already contain, and update the salary if the Person
object is already there.
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);
}
}
Note that for indexOf
to work correctly, your Person
object must override the equals
method, so that two persons with the same name are considered equal. e.g :
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;
}
}
Upvotes: 0
Reputation: 409
Don't forget that calling to persons.remove(per)
shall throw ConcurrentModificationException
.
You will need to iterate the List Iterator personsIter = persons.iterator()
then personsIter.remove(per)
Upvotes: 0
Reputation: 2943
You are just comparing same array element. You need to do this using two nested loops.
Upvotes: 0