0

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?

3
  • In your if you compare the name of a person with the name of the same person so it should always be true. The same with the salary. Commented Mar 22, 2017 at 10:28
  • 1
    Double salary for everyone ;-) Commented Mar 22, 2017 at 10:32
  • Perform remove element from the list while on the loop of that list is very bad practice, i thinks. Commented Mar 22, 2017 at 10:35

7 Answers 7

1

You forgot () on getName and getSalary.

Sign up to request clarification or add additional context in comments.

3 Comments

Another thing. You are comparing person with himself. You should make 2 for loops. so compare 1-1,1-2,1-3,2-1,2-2 etc.
Thanks, but It was just spelling mistake, not logical
You can use Set instead of List. In Set you cannot hold duplicates. If using set, make sure that you override equals and hashcode.
0

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

2 Comments

The best solution. Thanks a lot, but i wonder what why do we need to check if per1 != per2.
First of all, in this loop, it starts checking from the same index. So, it will start comparing itself to itself, which has the same name, but if you remove it, both (or the same) will be removed. Next to which, this is the same if one instance is added to the list twice, which shouldnt happen, but could.
0

You are just comparing same array element. You need to do this using two nested loops.

Comments

0

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)

Comments

0

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;
    }

}

Comments

0

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)]

Comments

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.