开发者

Sorting objects within a Set by a String value that all objects contain

Ok this is a tricky one. I have a list of Sets. I would like to sort the objects in the Sets in an order.

Imagine each set as repressenting a class in a school. Each set contains person objects. A person object holds a String value for name. I'd like to arrange the Persons in the Set by name before I loop through and write them out.

Is there anywahy to use Collections.sort(); or something similar to achieve this?

for (Set<Person> s : listOfAllChildren) {       
      for (Person p : s) {
        if(p.getClass().equalsIgnoreCas开发者_运维技巧e("Jones")){
          System.out.println(p.getName());
          }
         else if...//carry on through other classes 
        }                              
      }        

I do know that 2+ children in a class may share the same name but please ignore this


A Set has no notion of ordering because, well, it's a set.

There is a SortedSet interface implemented by TreeSet class that you can use. Simply provide an appropriate Comparator to the constructor, or let your Person class implements Comparable.


With Java 8 you can sort the Set of persons and generate List of persons which are sorted as follows.

List<Person> personList = personSet.stream().sorted((e1, e2) -> 
e1.getName().compareTo(e2.getName())).collect(Collectors.toList());


You must implement Comparable for your sortable objects (Person etc).

Then:

  1. Convert Set to List (some info here) since you can't sort a Set
  2. Use Collections.sort

or

  1. Convert to a SortedSet (like a TreeSet)
  2. Use a Comparator for custom ordering

Examples:

import java.util.*;

class Person implements Comparable<Person> {
    private String firstName, lastName;

    public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName;}
    public String getFirstName() {return firstName;}
    public String getLastName() {return lastName;}
    public String getName() {return firstName + " " + lastName;}

    public int compareTo(Person p) {
        return lastName.compareTo(p.lastName);
    }
}

class FirstNameComparator implements Comparator<Person> {
    public int compare(Person p1, Person p2){
            return p1.getFirstName().compareTo(p2.getFirstName());
    }
}

class Test {
  public static void log(String s) {
        System.out.println(s);
    }

  public static void main(String[] args) {
        Set<Person> people = new HashSet<Person>();
        people.add(new Person("Bob", "Jones"));
        people.add(new Person("Alice", "Yetti"));

        log("Sorted list:");
        List<Person> peopleList = new LinkedList<Person>();
        peopleList.addAll(people);
        Collections.<Person>sort(peopleList);
        for (Person p : peopleList) {
            log(p.getName());
        }

        log("TreeSet:");
        TreeSet<Person> treeSet = new TreeSet<Person>();
        treeSet.addAll(people);
        for (Person p : treeSet) {
            log(p.getName());
        }

        log("TreeSet (custom sort):");
        TreeSet<Person> treeSet2 = new TreeSet<Person>(new FirstNameComparator());
        treeSet2.addAll(people);
        for (Person p : treeSet2) {
            log(p.getName());
        }
      }
};


You can consider using TreeSet to store objects. And when sorting create new TreeSet with custom comparator for your Person objects. I do not suggest using Collection.sort because AFAIR it can sort only lists.


You could make your Person class implement the Comparable interface as shown here and then sort them accordingly.


You may want to look at using a SortedSet for example a TreeSet. This allows you to provide a Comparator which in your case can compare the name of the Person.


Yes! This you can definitely use Collection.sort(). But you will need to either use a sorted set (like TreeSet). Or, alternatively, you can first insert all the elements in the Set to a List.

Then, your Person class needs to implement Comparable, as this interface will be called by the Collections.sort() when it tries to decide in which order to place them. So it can be something simple like:

public class Person implements Comparable<Person> {
  ...
  @Override
  public int compareTo(Person p) {
    return this.name.compareTo(p.name);
  }
}

If using a TreeSet, it should be sorted already. Otherwise, if using a List, simply call Collections.sort(List l) on each list.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜