Сортировка объектов в наборе по строковому значению, которое содержат все объекты - PullRequest
5 голосов
/ 09 ноября 2010

Хорошо, это сложно. У меня есть список наборов. Я хотел бы отсортировать объекты в наборах в порядке.

Представьте, что каждый набор представляет класс в школе. Каждый набор содержит объекты человека. Объект person содержит строковое значение для имени. Я хотел бы расположить людей в наборе по имени, прежде чем я переберу их и выведу их.

Можно ли использовать Collections.sort(); или что-то подобное для достижения этой цели?

for (Set<Person> s : listOfAllChildren) {       
      for (Person p : s) {
        if(p.getClass().equalsIgnoreCase("Jones")){
          System.out.println(p.getName());
          }
         else if...//carry on through other classes 
        }                              
      }        

Я знаю, что 2+ детей в классе могут иметь одно и то же имя, но, пожалуйста, игнорируйте это

Ответы [ 7 ]

14 голосов
/ 09 ноября 2010

A Set не имеет понятия о порядке , потому что, ну, это набор.

Существует интерфейс SortedSet, реализованный классом TreeSet, который вы можете использовать. Просто предоставьте соответствующий Comparator конструктору, или пусть ваш Person класс реализует Comparable.

8 голосов
/ 09 ноября 2010

Вы должны реализовать Comparable для своих сортируемых объектов (Person и т. Д.).

Тогда:

  1. Преобразовать в список (некоторая информация здесь ), поскольку вы не можете отсортировать Set
  2. Использование Collections.sort

или

  1. Преобразовать в SortedSet (например, TreeSet )
  2. Используйте Comparator для индивидуального заказа

Примеры:

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());
        }
      }
};
6 голосов
/ 18 января 2017

С помощью Java 8 вы можете сортировать Set лиц и генерировать List людей, которые сортируются следующим образом.

List<Person> personList = personSet.stream().sorted((e1, e2) -> 
e1.getName().compareTo(e2.getName())).collect(Collectors.toList());
1 голос
/ 09 ноября 2010

Вы можете рассмотреть возможность использования TreeSet для хранения объектов.А при сортировке создайте новый TreeSet с пользовательским компаратором для ваших объектов Person.Я не предлагаю использовать Collection.sort, потому что AFAIR может сортировать только списки.

0 голосов
/ 09 ноября 2010

Вы можете посмотреть на SortedSet, например TreeSet. Это позволяет вам предоставить Comparator, который в вашем случае может сравнить имя Person.

0 голосов
/ 09 ноября 2010

Да! Это вы, безусловно, можете использовать Collection.sort (). Но вам нужно будет использовать отсортированный набор (например, TreeSet). Или, в качестве альтернативы, вы можете сначала вставить все элементы в Set to a List.

Затем ваш класс Person должен реализовать Comparable, так как этот интерфейс будет вызываться Collections.sort (), когда он попытается решить, в каком порядке их размещать. Так что это может быть что-то простое:

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

Если используется TreeSet, он должен быть уже отсортирован. В противном случае, если используется список, просто вызовите Collections.sort (List l) в каждом списке.

0 голосов
/ 09 ноября 2010

Вы можете заставить свой класс Person реализовать интерфейс Comparable , как показано здесь , а затем отсортировать их соответственно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...