簡體   English   中英

如何將具有相同值的多個鍵插入到 Java 中的哈希映射中?

[英]How to insert multiple keys with the same value into a hash map in Java?

我正在用 Java 進行以下編碼挑戰:

/**
     * 4. Given a word, compute the scrabble score for that word.
     * 
     * --Letter Values-- Letter Value A, E, I, O, U, L, N, R, S, T = 1; D, G = 2; B,
     * C, M, P = 3; F, H, V, W, Y = 4; K = 5; J, X = 8; Q, Z = 10; Examples
     * "cabbage" should be scored as worth 14 points:
     * 
     * 3 points for C, 1 point for A, twice 3 points for B, twice 2 points for G, 1
     * point for E And to total:
     * 
     * 3 + 2*1 + 2*3 + 2 + 1 = 3 + 2 + 6 + 3 = 5 + 9 = 14
     * 
     * @param string
     * @return
     */

我的想法是通過執行以下操作將所有這些字母插入哈希映射中:

map.add({A,,E,I,O,U,L,N,R,S,T}, 1);

有沒有辦法在 Java 中做到這一點?

您在評論中說過,您希望能夠在一個語句中添加所有這些條目。 雖然 Java 不是一種在單個語句中執行此類操作的好語言,但如果您真的下定決心這樣做,它是可以完成的。 例如:

Map<Character, Integer> scores =
    Stream.of("AEIOULNRST=1","DG=2","BCMP=3","FHVWY=4" /* etc */ )
        .flatMap(line -> line.split("=")[0].chars().mapToObj(c -> new Pair<>((char)c, Integer.parseInt(line.split("=")[1]))))
        .collect(Collectors.toMap(Pair::getKey, Pair::getValue));

System.out.println("C = " + scores.get('C'));

輸出:

C = 3

在上面的代碼中,我首先構建了一個包含所有條目(作為對)的流,並將它們收集到一個映射中。

筆記:

我在上面使用的 Pair 類來自javafx.util.Pair 但是,您可以輕松地使用AbstractMap.SimpleEntry 、您自己的 Pair 類或任何能夠容納兩個對象的集合數據類型。


更好的方法

另一個想法是編寫您自己的輔助方法。 這個方法可以放在一個包含類似輔助方法的類中。 這種方法會更慣用,更容易閱讀,因此更容易維護。

public enum MapHelper {
; // Utility class for working with maps
public static <K,V> void multiKeyPut(Map<? super K,? super V> map, K[] keys, V value) {
for(K key : keys) {
    map.put(key, value);
}}}

然后你會像這樣使用它:

Map<Character, Integer> scores = new HashMap<>();
MapHelper.multiKeyPut(scores, new Character[]{'A','E','I','O','U','L','N','R','S','T'}, 1);
MapHelper.multiKeyPut(scores, new Character[]{'D','G'}, 2);
MapHelper.multiKeyPut(scores, new Character[]{'B','C','M','P'}, 3);
/* etc */

取一個長度為 26 的數組,每個元素代表一個字母表的分數。 所以,我們將有一個這樣的數組:-

alphabetScore = [1,3,3,2,.....................];

現在,遍歷單詞,並在總分中不斷添加當前字母表的分數。

我認為將更多字符列表存儲為鍵(看看這個問題)和與該鍵對應的單個值不是一個好主意,但如果你真的需要那個,你可能想嘗試一下:

Map<ArrayList<Character>, Integer> map = new HashMap<>();
map.put(new ArrayList<Character>(Arrays.asList('A', 'E',...)), 1);
map.put(new ArrayList<Character>(Arrays.asList('D', 'G',...)), 2);

個人而言,我建議使用HashMap<Integer, ArrayList<Character>> - 鍵是一組字母的“值”(例如,對於包含字母的ArrayList ,鍵為 1:A、E 等),作為對應於的值Integer 鍵可以是存儲字符(A、E、...)的ArrayList 您可以通過以下方式實現該結果:

Map<Integer, ArrayList<Character>> map = new HashMap<>();
map.put(1, new ArrayList<Character>(Arrays.asList('A', 'E',...)));
map.put(2, new ArrayList<Character>(Arrays.asList('D', 'G',...)));

Map沒有對多個鍵進行操作的方法,但您可以流式傳輸這些字符的列表並調用forEach

Map<Character, Integer> scores = new HashMap<>();
Stream.of('A', 'E', 'I', 'O', 'U', 'L', 'N', 'R', 'S', 'T')
      .forEach(c -> scores.put(c, 1));
Stream.of('D', 'G').forEach(c -> scores.put(c, 2));
// etc...

一條線:

Map<String, Integer> map = Stream.of( "A", "E", "I", "O", "U", "L", "N", "R", "S", "T" ).collect( Collectors.toMap( Function.identity(), o -> 1 ) );

或者如果您已經有一個字符串列表

Collection<String> chars = new ArrayList<>();
// Add to collection
Map<String, Integer> map = chars.stream().collect( Collectors.toMap( Function.identity(), o -> 1 ) );

您可以使用相同的方法添加具有相同值的其他鍵

map.addAll( Stream.of( "F", "H", "V", "W", "Y" ).collect( Collectors.toMap( FUnction.identity(), o -> 4 );

最終,最好使用輔助函數來提高可讀性

private Map<String, Integer> mapScores( int score, String... letter ) {
    return Stream.of( letter ).collect( Collectors.toMap( Function.identity(), o -> score ) );
}

Map<String, Integer> map = new ConcurrentHashMap<>();
map.putAll( mapScores( 1, "A", "E", "I", "O", "U", "L", "N", "R", "S", "T" ) );
map.putAll( mapScores( 2, "D", "G" ) );
map.putAll( mapScores( 3, "B", "C", "M", "P" ) );
map.putAll( mapScores( 4, "F", "H", "V", "W", "Y" ) );
map.put( "K", 5 );
map.putAll( mapScores( 8, "J", "X" ) );
map.putAll( mapScores( 10, "Q", "Z" ) );

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM