1

Is it possible to compare attributes of objects in a list & if the attribute "name" happens to be the same then print out the one that is older (with the rest that does not have same name) and if their name & age happens to be the same then print out one of them (with the rest that does not have same name)? I need to compare a list with objects. I sorted the list and started with nestled for-loops but then got stuck. Are there better ways of doing this? Maybe placing some method in the Person class or another way?

enter code here
public class Person {



private String name;
private int age;

public Person(String name, int age) {
    this.name = name;
    this.age = age;
}



public String getName() {
    return name;
}



public int getAge() {
    return age;
    }

}

public class Main {
    public static void main(String[] args){
    Person[] persons = new Student[4];
    persons[0] = new Person("Erik",20);
    persons[1] = new Person("Bob",21);
    persons[2] = new Person("Erik",25);
    persons[3] = new Person("Fredrik",20);

    Arrays.sort(persons, Comparator.comparing(Person::getName));

    for (int i = 0; i<persons.length; i++)
        for(int j = 0; j<i; j++){
            if (persons[i].getAge() == persons[j].getAge())
                  
             }
       
        
        //output: Bob, Erik, Fredrik
       
    }
}
    
ZedORYasuo
  • 183
  • 7

2 Answers2

3

Since you only want each name to be once, and the oldest, you can create what's called a HashMap, ( Key-> value association with unique key) in which you store only the oldest person

Once you have this hashmap, you then can iterate through it to print exactly what you want

Example :

public static void main(String[] args){
    Person[] persons = new Student[4];
    persons[0] = new Person("Erik",20);
    persons[1] = new Person("Bob",21);
    persons[2] = new Person("Erik",25);
    persons[3] = new Person("Fredrik",20);

    HashMap<String, Integer> oldest_people = new HashMap<>();
    for (Person p: persons){
        int person_age = oldest_people.getOrDefault(p.getName(), -1);
        if (person_age != -1) {
            if (p.getAge() > person_age) {
                oldest_people.put(p.getName(), p.getAge());
            }
        }
        else {
            oldest_people.put(p.getName(), p.getAge());
        }
    }


    for (Map.Entry<String, Integer> entry : oldest_people.entrySet()) {
        System.out.println(entry.getKey() + " age : "+entry.getValue().toString());
    }
}
            
  • Thank you sir! It kind of worked, but now I just get the ones with the same name to be printed. I loved btw the second approach. So I want all the names to be printed and if they happens to have same name then only once (the oldest of them). In this approach I get all with the same name and the rest "false" because they are not the same. – ZedORYasuo Sep 17 '22 at 08:33
  • "if the attribute "name" happens to be the same then only print out the one that is older and if their name & age happens to be the same then only print out one of them?" You asked for that, but do I have to guess that if they don't have the same name, then you want both of same to be printed? Because what you asked and what you printed are quite different, if you just want every single different name to be printed, then the approach should be different – Sparkling Marcel Sep 17 '22 at 08:51
  • you are right. let me edit the question. However in my code I marked what the output should be – ZedORYasuo Sep 17 '22 at 08:53
  • sorry for the trouble. Now I fixed it – ZedORYasuo Sep 17 '22 at 08:56
  • Np, but then the approach has to be different, let me find a way and edit my response – Sparkling Marcel Sep 17 '22 at 09:00
  • 1
    I Edited my post with the new solution, tested it and it works as you'd want I think, if there's something you don't understand, don't hesitate – Sparkling Marcel Sep 17 '22 at 09:13
  • I have a question if you dont mind. If I want to add an attribute to the class let say "email". Is it possible to use the same approach and just include "email" in the print? So for example: "Erik 25 erik@hotmail.com"? I know that a hashmap only takes in 2 values thats why im asking. – ZedORYasuo Sep 17 '22 at 09:37
  • 1
    Yes totally, you could even add the Person as a value (Key -> name, value -> the Person Object) Then you'd just have to change the code slightly to adapt, but if you do that it will be totally futur proof to any change since you'll always have access to the person object. If you don't find how to do you can pm me on stack to not pollute the comment – Sparkling Marcel Sep 17 '22 at 09:42
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/248131/discussion-between-zedoryasuo-and-sparkling-marcel). – ZedORYasuo Sep 17 '22 at 10:40
0

Alternate approach based on your program, override these below methods on a Person class

@Override
public int hashCode() {
    return name.hashCode();
}

@Override
public boolean equals(Object obj) {
    if(obj == null || !(obj instanceof Person)) return false;
    Person p = (Person) obj;
    if(this.name.equals(p.getName())) return true;          
    return false;
}

And you can add custom comparator to sort person on the array

Comparator<Person> comparePerson = new Comparator<Person>() {
    @Override
    public int compare(Person p1, Person p2) {
        //name in ascending order
        int nameCompare = p1.getName().compareTo(p2.getName());
        
        //age in descending order means from higher age 
        int ageCompare = Integer.compare(p2.getAge(), p1.getAge()); 
        
        return  nameCompare == 0 ? ageCompare : nameCompare;
    }
};

Arrays.sort(persons, comparePerson);

After, you can find unique Person. Below, the Set collection will only add a unique Person, this time oldest age person will add.

Set<Person> personSet = new HashSet<>();
for(Person p : persons) {
    if(!personSet.contains(p)) personSet.add(p);
}

Now, you can get a unique Person in collection.

Sawan Meshram
  • 230
  • 2
  • 12