Как вернуть ключ, если элемент существует в List из Hash? - PullRequest
0 голосов
/ 27 февраля 2019

Мне нужно получить ключ, если список в ключе содержит определенное значение в нем.

Единственное, что я могу придумать, это итерация HashMap, а также цикл for для списка значений каждого ключа.а затем проверьте, содержит ли список значение, и верните ключ.Примерно так:

Map<String, List<MyItem>> map = new HashMap<>();
List<MyItem> list = new List<>();
list.add(new MyItem("Kim", 25);
list.add(new MyItem("Lee", 28);
map.put("Samsung", list);

String searchKeyWord = "Kim";
String myKey = getKeyByValue(map, searchKeyWord);

System.out.println("Found Key: " + myKey);

Я не знаю, что лучше.

1.

public String getKeyByValue(Map<String, List<MyItem> map, String searchKeyWord) {
    boolean flag = false;
    String myKey = null;

    for (Entry<String, List<MyItem>> e : map.entrySet()) {
        String currentKey = e.getKey();
        List<MyItem> myItemList = e.getValue();
        Collections.sort(myItemList, this);
        for (int i = 0 ; i < myItemList.size() ; i++) {
            if (myItemList.get(i).name.equals(searchKeyWord)) {
                myKey = currentKey;
                flag = true;
            }
            if (flag) {
                break;
            }
        }
        if (flag) {
            break;
        }
    }
    return (flag ? myKey : null);
}

2.

public String getKeyByValue(Map map, String searchKeyWord){
    boolean flag = false;
    String myKey = null;

    for(Entry<String, List<MyItem>> e: map.entrySet()){
        String currentKey = e.getKey();
        List<MyItem> myItemList = e.getValue();
        Collections.sort(myItemList, this);
        if(binarySearch(myItemList, searchKeyWord)){
            myKey = currentKey;
            flag = true;
        }
    }

    if(flag) return myKey;
    else null;
}
Использование HashMap вместо List. Использование нескольких значений (Guava)

Или другие методы ...

Следует ли изменить структуру данных?Какой лучший алгоритм поиска для этого?

1 Ответ

0 голосов
/ 27 февраля 2019

Объяснение в комментариях:

private static String getKeyByValue(Map<String, List<MyItem>> map, String searchKeyWord) {
    return map.entrySet().stream()      //all entries in the map
            .filter(e -> e.getValue().stream()
                    .anyMatch(i -> i.getName().equals(searchKeyWord))) //take only the ones which have searchKeyword in their list
            .findAny()                  //take just one such entry
            .map(Map.Entry::getKey)     //change Entry to String (the key)
            .orElse(null);              //if there is no such entry, return null
}

Как подсказал @MCEmperor, вы можете изменить String на Optional<String> тип возвращаемого значения и избавиться от .orElse(null);.


Или, если у вас много элементов, вы можете избежать сканирования целых списков, используя такую ​​структуру данных, как Map<String, Map<String, MyItem>>, например:

Map<String, Map<String, MyItem>> m = new HashMap<>();

Map<String, MyItem> items = Map.of(
        "Kim", new MyItem("Kim", 25),
        "Lee", new MyItem("Lee", 28)
);

m.put("Samsung", items);

String result = m.entrySet().stream()
        .filter(e -> e.getValue().containsKey(searchKeyWord))
        .findAny()
        .map(Map.Entry::getKey)
        .orElse(null);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...