해시 맵에서 추출한 주문 된 값 목록을 어떻게 형성 할 수 있습니까?

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

다른 팁

불행히도 인식 가능한 순서로 해시 맵에서 데이터를 꺼내는 방법은 없습니다. FileID를 사용하는 비교기를 사용하여 모든 값을 트리셋에 넣거나 ArrayList에 넣고 Collections.Sort로 정렬해야합니다.

중복이있는 경우 TreeSet 방법이 작동하지 않으며 세트에서 물건을 추가하거나 제거하지 않기 때문에 과잉 일 수 있습니다. Collections.sort 메소드는 해시 세트 전체를 가져 가서 결과를 정렬 한 다음 결과를 생성하자마자 정렬 된 컬렉션을 버릴 경우 좋은 솔루션입니다.

OK, this is what I've come up with. Seems to solve the problem, returns a String with the File objects nicely ordered by their 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();
}

I've never used Comparator before (relatively new to Java), so would appreciate any feedback if I've implemented anything incorrectly.

Why not collect it in an array, sort it, then concatenate it?

-- MarkusQ

You'll have to add your values() Collection to an ArrayList and sort it using Collections.sort() with a custom Comparator instance before iterating over it.

BTW, note that it's pointless to initialize the StringBuffer with the size of the collection, since you'll be adding far more than 1 character per collection element.

Create a temporary List, then add each pair of data into it. Sort it with Collections.sort() according to your custom comparator then you will have the List in your desired order.

Here is the method you're looking for: http://java.sun.com/javase/6/docs/api/java/util/Collections.html#sort(java.util.List,%20java.util.Comparator)

I created LinkedHashMap a dozen times before it was added to the set of collections.

What you probably want to do is create a TreeHashMap collection.

Creating a second collection and appending anything added to both isn't really a size hit, and you get the performance of both (with the cost of a little bit of time when you add).

Doing it as a new collection helps your code stay clean and neat. The collection class should just be a few lines long, and should just replace your existing hashmap...

If you get in the habit of always wrapping your collections, this stuff just works, you never even think of it.

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

Unless all your file.toString() is one character on average, you are probably making the StringBuffer too small. (If it not right, you may as well not set it and make the code simpler) You may get better results if you make it some multiple of the size. Additionally StringBuffer is synchronized, but StringBuilder is not and there for more efficient here.

Remove unnecessary if statment.

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