Как сформировать упорядоченный список значений, извлеченных из HashMap?

StackOverflow https://stackoverflow.com/questions/603766

  •  03-07-2019
  •  | 
  •  

Вопрос

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

у меня есть 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 сорт.

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

Это было полезно?

Решение

Что-то вроде этого должно работать:

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);                         
                     }
                 });

Другие советы

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

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

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

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), поэтому буду признателен за любые отзывы, если я что-то реализовал неправильно.

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

-- МаркусКью

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

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

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

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

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

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

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

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

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

StringBuffer allFilesString = new StringBuffer(fileCollection.size());

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

Удалить ненужное 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);
                 }
             });
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top