2017-08-25 43 views
0

我試圖從我的哈希映射中找到n個值並將它們放入不同的列表中以分配給不同的字體大小。我有不同列表中的最大值和第二最大值,但是當我嘗試第三或第四等時,它會添加已經被發現的單詞,只有最後一個單詞是不同的。有可能比關鍵字(單詞)具有相同的值,因此通過索引進行排序並不是真正的選擇。你能幫我嗎。在Java中查找n值時排除搜索時的值

//searching for biggest value 
    for (Map.Entry<String, Integer> en : wordToCountMap.entrySet()) { 
     if (max1 == null || en.getValue().compareTo(max1.getValue()) > 0) { 
      max1 = en; 
      largestList.clear(); 
      largestList.add(max1.getKey()); 
     } 
    } 
    //searching for second largest value 
    for (Map.Entry<String, Integer> en : wordToCountMap.entrySet()) { 
     if (en != max1 && (max2 == null || (en.getValue().compareTo(max2.getValue()) > 0))) { 
      max2 = en; 

      secondlargestList.add(max2.getKey()); 
     } 
    } 
    //searching for third largest value 
    for (Map.Entry<String, Integer> en : wordToCountMap.entrySet()) { 
     if (en != max1 && en != max2 && (max3 == null || (en.getValue().compareTo(max3.getValue()) > 0))) { 
      max3 = en; 

      thirdlargestList.add(max3.getKey()); 
     } 
    } 

其輸出 [季節] [居多,去,多少,季節,一] [居多,去,大,四季]

+1

我不明白你正在嘗試做的,閱讀代碼是沒有幫助。 –

回答

0

真的需要一些時間來了解你想要做什麼。 我認爲你應該首先得到條目的值作爲列表 - 你可以很容易地排序。

List<Integer> values = wordToCountMap.values().stream.collect(Collectors.toList()); 
Collections.sort(values); 
Collections.reverse(values); 

現在,數值從高到低排序,您可以使用該列表。

Integer highestValue = values.get(0); 
List<String> wordsWithHighestValue = wordToCountMap.entrySet().stream() 
          .filter(e -> e.getValue().equals(highestValue)) 
          .collect(Collectors.toList()); 

但是,我可能會先創建具有相同計數的單詞列表。

NavigableMap<Integer,List<String>> countToWordsMap = new TreeMap<>(wordToCountMap.stream() 
    .collect(Collectors.groupingBy(Map.Entry::getValue, 
          Collectors.mapping(Map.Entry::getKey, Collectors.toList()))); 

還是有點更具可讀性

NavigableMap<Integer,List<String>> countToWordsMap = new TreeMap<>(); 
for (Map.Entry<String,Integer> entry : wordToCountMap.entrySet()) { 
    Integer count = entry.getValue(); 
    List<String> list = countToWordsMap.computeIfAbsent(count, new ArrayList<String>()); 
    list.add(entry.getKey()); 
    countToWordsMap.put(count, list); 
} 
+0

對不起,使用最後一塊代碼中的新ArrayList <>中的<>,我得到無法推斷參數 –

+0

@JakeFishlock編輯以添加類型。 – daniu

0

您需要檢查:

en.getValue() != max2.getVaue(); 

因爲你不能比較對象:

en != max2; 
0

如果我理解正確的話,你想檢索詞的最高計數的列表。這是一些代碼。希望這將有助於:

/** 
* This is only convenient facade, using in tests. 
* 
* @param wordMap 
* @param level 
* @return 
*/ 
public List<String> getMaxList(Map<String, Integer> wordMap, int level) { 
    return getMaxList(wordMap.entrySet(), level); 
} 

/** 
* Returns list of words with highest counts, from highest to lowest 
* 
* @param wordMapEntrySet 
* @param level indicates how many words with highest count you want. 
* @return 
*/ 
private List<String> getMaxList(Set<Map.Entry<String, Integer>> wordMapEntrySet, int level) { 

    //Convert set to list, because set is not sortable 
    List<Map.Entry<String, Integer>> list = new ArrayList<>(wordMapEntrySet); 

    //Sort the list 
    list.sort((mapEntry1, mapEntry2) -> { 
     //Comparing two entries - comparing values (which is actualy a word count) 
     //Ordering from highest value to lowest 
     //Changing compare to mapEntry1...compareTo(mapEntry2) will sort the list in reverse order, i.e. from lowest to highest 
     return mapEntry2.getValue().compareTo(mapEntry1.getValue()); 
    }); 

    //Return a sublist of the sorted list 
    //Need to return only the keys from the Map.Entry, because the word is the key. 
    return list.subList(0, level).stream().map(stringIntegerEntry -> stringIntegerEntry.getKey()).collect(Collectors.toList()); 
} 

下面是測試單元測試:

public class WordCountTest { 

    WordCount wc = new WordCount(); 

    private Map<String, Integer> createMap() { 
     Map<String, Integer> wordMap = new HashMap<>(); 
     wordMap.put("AA", 3); 
     wordMap.put("AB", 30); 
     wordMap.put("AC", 300); 
     wordMap.put("AD", 3000); 
     wordMap.put("AE", 30000); 
     wordMap.put("AF", 1000); 
     wordMap.put("AG", 100); 
     wordMap.put("AH", 10); 
     wordMap.put("AI", 1); 
     return wordMap; 
    } 

    private Map<String, Integer> createMapSame() { 
     Map<String, Integer> wordMap = new HashMap<>(); 
     wordMap.put("AA", 3); 
     wordMap.put("AB", 30); 
     wordMap.put("AC", 300); 
     wordMap.put("AD", 3000); 
     wordMap.put("AE", 30000); 
     wordMap.put("AF", 30000); 
     wordMap.put("AG", 3000); 
     wordMap.put("AH", 300); 
     wordMap.put("AI", 30); 
     return wordMap; 
    } 


    @Test 
    public void testMaxWordCount() { 
     List<String> maxWordList = wc.getMaxList(createMap(),3); 
     Assert.assertEquals(maxWordList.get(0), "AE"); 
     Assert.assertEquals(maxWordList.get(1), "AD"); 
     Assert.assertEquals(maxWordList.get(2), "AF"); 
    } 


    @Test 
    public void testMaxWordCountWithSameCount() { 
     List<String> maxWordList = wc.getMaxList(createMapSame(), 4); 
     Assert.assertEquals(maxWordList.get(0), "AE"); 
     Assert.assertEquals(maxWordList.get(1), "AF"); 
     Assert.assertEquals(maxWordList.get(2), "AD"); 
     Assert.assertEquals(maxWordList.get(3), "AG"); 
    } 

}