Как мне сформировать упорядоченный список значений, извлеченных из HashMap? - PullRequest
0 голосов
/ 02 марта 2009

Моя проблема на самом деле более нюансирована, чем предполагает вопрос, но я хотел, чтобы заголовок был кратким.

У меня есть HashMap<String, File> из File объектов в качестве значений. Ключи - это поля String name, которые являются частью экземпляров File. Мне нужно перебрать значения в HashMap и вернуть их как один String.

Это то, что у меня сейчас есть:

private String getFiles()
{   
    Collection<File> fileCollection = files.values();
    StringBuilder allFilesString = new StringBuilder();

    for(File file : fileCollection) {
        allFilesString.append(file.toString());
    }
    return allFilesString.toString();
}

Это делает работу, но в идеале я хочу, чтобы отдельные значения File были добавлены к StringBuilder в порядке int fileID, который является полем класса File.

Надеюсь, я прояснил это достаточно.

Ответы [ 9 ]

6 голосов
/ 02 марта 2009

Примерно так должно работать:

List<File> fileCollection = new ArrayList<File>(files.values());

Collections.sort(fileCollection, 
                 new Comparator<File>() 
                 {
                     public int compare(File fileA, File fileB) 
                     {
                         final int retVal;

                         if(fileA.fileID > fileB.fileID)
                         {
                             retVal = 1;
                         }
                         else if(fileA.fileID < fileB.fileID)
                         {
                             retVal = -1;
                         }
                         else
                         {
                             retVal = 0;
                         }

                         return (retVal);                         
                     }
                 });
4 голосов
/ 02 марта 2009

К сожалению, нет никакого способа извлечь данные из HashMap в любом распознаваемом порядке. Вы должны либо поместить все значения в TreeSet с помощью Comparator, который использует fileID, либо поместить их в ArrayList и отсортировать их с Collections.sort, снова с Comparator, который сравнивает, как вы хотите.

Метод TreeSet не работает, если есть какие-либо дубликаты, и он может быть излишним, поскольку вы не собираетесь добавлять или удалять объекты из набора. Метод Collections.sort является хорошим решением для таких случаев, когда вы собираетесь взять весь HashSet, отсортировать результаты, а затем выбросить отсортированную коллекцию, как только вы сгенерируете результат.

1 голос
/ 05 марта 2009

ОК, это то, что я придумал. Кажется, чтобы решить проблему, возвращает строку с объектами File, упорядоченными по их fileId.

public String getFiles()
{   
    List<File> fileList = new ArrayList<File>(files.values());

    Collections.sort(fileList, new Comparator<File>()
                               {
                                   public int compare(File fileA, File fileB)
                                   {
                                       if(fileA.getFileId() > fileB.getFileId()) 
                                       {
                                           return 1;
                                       }
                                       else if(fileA.getFileId() < fileB.getFileId()) 
                                       {
                                           return -1;
                                       }
                                       return 0;
                                   }
                               });

    StringBuilder allFilesString = new StringBuilder();

    for(File file : fileList) {
        allFilesString.append(file.toString());
    }
    return allFilesString.toString();
}

Я никогда не использовал Comparator (относительно новый для Java), поэтому буду признателен за любые отзывы, если я что-то неправильно реализовал.

0 голосов
/ 12 марта 2009

Удалите ненужные if комментарии.

List<File> fileCollection = new ArrayList<File>(files.values());
Collections.sort(fileCollection, 
             new Comparator<File>() {
                 public int compare(File a, File b) {
                     return (a.fileID - b.fileID);
                 }
             });
0 голосов
/ 04 марта 2009
StringBuffer allFilesString = new StringBuffer(fileCollection.size());

Если все ваши file.toString () не являются в среднем одним символом, вы, вероятно, делаете StringBuffer слишком маленьким. (Если это не правильно, вы также можете не устанавливать его и делать код проще). Вы можете получить лучшие результаты, если вы сделаете его несколько кратным размеру. Кроме того, StringBuffer синхронизируется, а StringBuilder - нет, и для более эффективной работы здесь.

0 голосов
/ 02 марта 2009

Я создал LinkedHashMap десятки раз, прежде чем он был добавлен в набор коллекций.

Что вы, вероятно, хотите сделать, это создать коллекцию TreeHashMap.

Создание второй коллекции и добавление чего-либо, добавленного к обоим, на самом деле не является достижением в размере, и вы получаете производительность обоих (с добавлением стоимости времени).

Создание новой коллекции помогает вашему коду оставаться чистым и аккуратным. Класс коллекции должен быть длиной в несколько строк и должен просто заменить существующую хэш-карту ...

Если у вас есть привычка всегда оборачивать свои коллекции, этот материал просто работает, вы даже не думаете об этом.

0 голосов
/ 02 марта 2009

Создайте временный список, затем добавьте в него каждую пару данных. Сортируйте его с помощью Collections.sort () в соответствии с вашим пользовательским компаратором, и вы получите список в нужном вам порядке.

Вот метод, который вы ищете: http://java.sun.com/javase/6/docs/api/java/util/Collections.html#sort(java.util.List,%20java.util.Comparator)

0 голосов
/ 02 марта 2009

Вам нужно будет добавить коллекцию values ​​() в ArrayList и отсортировать ее с помощью Collections.sort () с пользовательским экземпляром Comparator, прежде чем итерировать по нему.

Кстати, обратите внимание, что бессмысленно инициализировать StringBuffer размером коллекции, так как вы будете добавлять гораздо больше, чем 1 символ на элемент коллекции.

0 голосов
/ 02 марта 2009

Почему бы не собрать его в массив, не отсортировать и не объединить?

- MarkusQ

...