Найти ключ объекта из HashMap - PullRequest
3 голосов
/ 09 марта 2011

У меня есть HashMap с ключом в качестве моего собственного объекта и ключом ArrayList из String.Есть ли способ получить ключевой объект с карты, который равен другому объекту без итерации карты.Обратите внимание, что в моем объекте реализован метод equals & hashcode.И он использует только 2 атрибута класса для сравнения.Другой объект, который я пытаюсь найти в ключах карты, имеет те же два атрибута, но другие атрибуты могут отличаться в ключе карты.

//The actual map
private HashMap<FileDetail, ArrayList<String>> map = new HashMap<FileDetail, ArrayList<String>>();
//object to search in above map without iteration.
FileDetail file = some object;

Я хочу получить ссылку на объект "файл" в ключах карты.

Ответы [ 7 ]

4 голосов
/ 09 марта 2011

Нет, ты не можешь этого сделать. HashMap должен работать по-другому: у вас есть ключ, вы ищете объект.

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

2 голосов
/ 09 марта 2011

Если вы не хотите перебирать набор ключей, вы можете использовать Guava's BiMap . BiMap имеет обратное представление, которое является еще одним bimap, содержащим обратные ключи и значения. Вот как вы бы это использовали:

BiMap<FileDetail, ArrayList<String>> biMap = HashBiMap.create();

//object to search in above map without iteration.
FileDetail file = some object;

FileDetail key = biMap.inverse().get(biMap.get(file));
1 голос
/ 12 апреля 2016

Этому вопросу пять лет, но у меня был тот же вопрос только сегодня, и я нашел эту страницу.Я думал, что поделюсь решением, которое я решил использовать, которое не описано ни в одном из существующих ответов и избегает перебора всех ключей на карте.(Пожалуйста, будьте осторожны, это моя первая публикация на SO. Трудно найти вопросы, на которые я могу ответить, на которые еще нет ответов. Более того, каждый вопрос, который у меня был до сих пор, уже задавался на SO. Я использовалТак что в течение многих лет, без возможности комментировать или голосовать за ответы.)

Как уже было сказано, карты разрабатываются таким образом, что, когда у вас есть ключ, вы ищите значение.В этом случае ответом является использование ключа также в качестве значения, чтобы при выполнении поиска с использованием произвольного ключа, который equals является вашим исходным ключом, но не обязательно ==, вы получаете обратнооригинальный ключ.Тогда возникает вопрос: как получить то, что изначально предполагалось использовать в качестве значения?

Мое решение зависит от наличия контроля над классом, используемым для ключа, и контроля над картой с возможностью переопределения их,который, кажется, имеет место для OP.В примере OP это будет контроль класса FileDetail и закрытой переменной map.Предполагая такой контроль, класс FileDetail будет изменен, чтобы он содержал переменную-член типа ArrayList<String>, которую для моего примера кода ниже я буду называть list, со связанными методами set и getter.Для закрытой переменной map она будет определена следующим образом:

private HashMap<FileDetail, FileDetail> map = new HashMap<>();

Теперь, когда вы хотите put новый ArrayList<String> объект на карте, назначенный определенной клавише FileDetailВы вместо этого назначаете объект ArrayList<String> переменной-члену FileDetail ArrayList<String>, а затем помещаете объект FileDetail в map.

public void putInMap(FileDetail fd, ArrayList<String> al) {
    // Ignoring null conditions for simplicity...
    fd.setList(al);
    map.put(fd, fd);
}

Позже, когда получитенекоторый произвольный объект FileDetail (тот, который equals является ключом, но не обязательно == к нему), и вам нужен связанный ключ, это вопрос обычного поиска:

FileDetail otherFd = getArbitraryFileDetail();
FileDetail originalKeyFd = map.get(otherFd);

И чтобы получить связанный ArrayList<String> после выполнения вышеупомянутого:

ArrayList<String> al = originalKeyFd.getList();

Конечно, все это зависит от реализаций методов equals и hashCode класса FileDetail, ноУ OP уже были те методы, которые были определены как нужные.

Надеюсь, это поможет любому, кто, как и я, заходит на эту страницу в аналогичной ситуации.

0 голосов
/ 10 марта 2011

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

Map<FileDetail, Pair<FileDetail, List<String>>>

Если вы не можете изменить тип карты, вы можете использовать секунду Map<FileDetail, FileDetail>, где ключ и значение всегда являются одинаковыми объектами.

0 голосов
/ 10 марта 2011

Мы получаем ключевой объект из Hashmap без итерации набора ключей HashMap путем преобразования набора ключей в ArrayList.Это простой пример:

//Creating hashmap
HashMap<String, String> map = new HashMap<String, String>();

//Adding elements into the map  
map.put("1", "Amit");
map.put("2", "Ananth");
map.put("3", "Sunil");

//Get the list from keyset
ArrayList myKeyList = new ArrayList(map.keySet());

//object to search in above map without iteration.
String myobj = "3";
System.out.println(myKeyList.get(myKeyList.indexOf(myobj)));
0 голосов
/ 09 марта 2011

В Java HashMap связывает ключ со значением, а не наоборот.

Вы можете получить Set всех ключей, используя HashMap.keySet()или альтернативно переберите все записи, используя HashMap.entrySet():

for (Entry <FileDetail, ArrayList<String>> entry : map.entrySet()) {
    FileDetail key = entry.getKey();
    if (shouldProcess(key)) {
        ArrayList<String> list = entry.getValue();
        processList(list);
    }
}
0 голосов
/ 09 марта 2011

Вы, вероятно, ищете двунаправленную карту, Apache Commons Collections включает это как часть библиотеки (я уверен, что есть и другие варианты). Двунаправленная карта, как следует из названия,карта, но написанная так, чтобы сделать поиск по ключу или по значению эффективным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...