2

There is a collection of 20 objects of a POJO class. I Want to write a method that return objects with distinct value. Now this is my Pogo class

class Student {

    private String firstName;

    private String lastName;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName( String firstName ) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName( String lastName ) {
        this.lastName = lastName;
    }
}

Now i want some method which returns unique last names values. I could not understand which logic i have to put in this.

Ronak Joshi
  • 1,553
  • 2
  • 20
  • 43

6 Answers6

1

If you are using something like Eclipse, you can right-click the source and select Source > "Generate hashCode() and equals()...". Doing so will yield something like this:

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());
    result = prime * result + ((lastName == null) ? 0 : lastName.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Student other = (Student) obj;
    if (firstName == null) {
        if (other.firstName != null)
            return false;
    } else if (!firstName.equals(other.firstName))
        return false;
    if (lastName == null) {
        if (other.lastName != null)
            return false;
    } else if (!lastName.equals(other.lastName))
        return false;
    return true;
}

Then, you'll want to add your objects to an instance of Set, maybe HashSet. Sounds like you can just return the populated Set then.

See also this.

EDIT: Note that I am not suggesting to put all of this on the Student class. The code shown above goes on Student, but the method that returns the set of distinct students goes somewhere else.

EDIT 2: If you are only interested in unique last names, you could modify hashCode() and equals() to not consider first name, but I concede that this would be quite unintuitive and recommend to avoid this in any circumstance other than an academic exercise. So, more correct might be to layer on an instance of Comparator that only considers last name--see doc and this.

Community
  • 1
  • 1
unigeek
  • 2,656
  • 27
  • 27
0

You can use an Arraylist, it has a built in function called .contains() which checks if the arrayList contains a specific value. So you would create an arrayList of last names and if it doesn't exist in the array list, just add it. See http://docs.oracle.com/javase/1.5.0/docs/api/java/util/ArrayList.html#contains(java.lang.Object)

Greg
  • 1
0

You can try to use Set, if you need to get only one field, or Map, if you need to know object(student) with this field. If you need to know all distinct Students (pair: first name + surname), you need to override getHashCode() and equals methods and use HashSet, HashMap

Natalia
  • 4,362
  • 24
  • 25
0

An easy way (for a beginner) to do this is just create a new array (same size of the input array). Then to loop through your array then compare every value to every other value in the array. If you can't find a match, then put this value in the new array.

Pseudo code:

public static Student[] GetUniqueLastNames(Student[] students){
    Student[] retArray;//new array
    for(i = 0; i < students.size; i++){
        unique = true
        for(j=0; j < students.size; j++){
            if(i != j){//make sure its not comparing the same value
                if(students[i].lastname.equals(students[j].lastname)){
                    unique = false
                    break
                }
            }
        }
        if(unique){
            retArray[i] = students[i]
        }
    }
    return retArray
}

Note: There are far better ways of doing this, but this is a nice basic way to do it if you're learning Java (or programming in general).

0

If you don't care about keeping the order of the objects, you can use a set:

public static <S extends Student> Collection<S> uniqByLastName(Collection<S> source){
    TreeSet<S> result = new TreeSet<S>(new Comparator<S>() {
        @Override
        public int compare(S s1, S s2) {
            return s1.getLastName().compareTo(s2.getLastName());
        }
    });
    result.addAll(source);
    return result;
}

If you care about the order

public static <S extends Student> Collection<S> uniqByLastName(Collection<S> source){
    Collection<S> result = new ArrayList<S>();
    Set<String> addedStudents = new HashSet<String>();
    for(S student : source){
        String lastName = student.getLastName();
        if(!addedStudents.contains(lastName)){
            result.add(student);
            addedStudents.add(lastName);
        }
    }
    return result;
}

If you want to modify the collection without returning a new one

public static <S extends Student> void uniqByLastName(Collection<S> source){
    Set<String> addedStudents = new HashSet<String>();
    Iterator<S> iterator = source.iterator();
    while(iterator.hasNext()){
        S student = iterator.next();
        String lastName = student.getLastName();
        if(addedStudents.contains(lastName)){
            iterator.remove();
        } else {
            addedStudents.add(lastName);
        }
    }
}
Volune
  • 4,324
  • 22
  • 23
0

If you are using Java 8, you can use lambda expression to solve it. Using following code snippet should solve your problem:

list.stream().collect(Collectors.toMap(Student::getLastName, p -> p, (p, q) -> p)).values();

Note: it will return first student with a given last name and as you might have already guessed, you don't need to override equals and hashcode.

Bagira
  • 2,149
  • 4
  • 26
  • 55