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:
- Convert Set to List (some info here) since you can't sort a
Set
- Use
Collections.sort
or
- Convert to a SortedSet (like a TreeSet)
- 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.
精彩评论