Как получить одну запись из hashmap без итерации

Есть ли элегантный способ получить только один Entry<K,V> из HashMap, без повторения, если ключ неизвестен.

Поскольку порядок ввода записи не важен, можем ли мы сказать что-то вроде

hashMapObject.get(zeroth_index);

Хотя я знаю, что такого метода get по индексу не существует.

Если я попробовал подход, упомянутый ниже, , он все равно должен был бы получить весь набор записей hashmap.

for(Map.Entry<String, String> entry : MapObj.entrySet()) {
    return entry;
}

Предложения приветствуются.

РЕДАКТИРОВАТЬ: Пожалуйста, предложите любую другую структуру данных, достаточную для выполнения требований.

Ответ 1

Ответ Джеспера хорош. Другое решение - использовать TreeMap (вы просили другие структуры данных).

TreeMap<String, String> myMap = new TreeMap<String, String>();
String first = myMap.firstEntry().getValue();
String firstOther = myMap.get(myMap.firstKey());

TreeMap имеет накладные расходы, поэтому HashMap работает быстрее, но как пример альтернативного решения.

Ответ 2

Карты не упорядочены, поэтому нет такой вещи, как "первая запись", а также почему нет метода get-by-index на Map (или HashMap).

Вы можете сделать это:

Map<String, String> map = ...;  // wherever you get this from

// Get the first entry that the iterator returns
Map.Entry<String, String> entry = map.entrySet().iterator().next();

(Примечание: проверка пустой карты опущена).

Ваш код не получает все записи на карте, он немедленно возвращается (и выходит из цикла) с первой найденной записью.

Чтобы напечатать ключ и значение этого первого элемента:

System.out.println("Key: "+entry.getKey()+", Value: "+entry.getValue());

Примечание. Вызов iterator() не означает, что вы выполняете итерацию по всей карте.

Ответ 3

Я думаю, что итератором может быть простейшее решение.

return hashMapObject.entrySet().iterator().next();

Другое решение (не очень):

return new ArrayList(hashMapObject.entrySet()).get(0);

Или еще (не лучше):

return hashMapObject.entrySet().toArray()[0];

Ответ 4

Получить значения, преобразовать их в массив, получить первый элемент массива:

map.values().toArray()[0]

Ш.

Ответ 5

Почему вы хотите избежать вызова entrySet(), он обычно не создает совершенно новый объект со своим собственным контекстом, а вместо этого просто предоставляет объект фасада. Проще говоря, entrySet() - довольно дешевая операция.

Ответ 6

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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SuppressWarnings("unchecked")
public class IndexedMap extends HashMap {

    private List<Object> keyIndex;

    public IndexedMap() {
        keyIndex = new ArrayList<Object>();
    }

    /**
     * Returns the key at the specified position in this Map keyIndex.
     * 
     * @param index
     *            index of the element to return
     * @return the element at the specified position in this list
     * @throws IndexOutOfBoundsException
     *             if the index is out of range (index < 0 || index >= size())
     */
    public Object get(int index) {
        return keyIndex.get(index);
    }

    @Override
    public Object put(Object key, Object value) {

        addKeyToIndex(key);
        return super.put(key, value);
    }

    @Override
    public void putAll(Map source) {

        for (Object key : source.keySet()) {
            addKeyToIndex(key);
        }
        super.putAll(source);
    }

    private void addKeyToIndex(Object key) {

        if (!keyIndex.contains(key)) {
            keyIndex.add(key);
        }
    }

    @Override
    public Object remove(Object key) {

        keyIndex.remove(key);
        return super.remove(key);
    }
}

ИЗМЕНИТЬ: Я сознательно не вникал в сторону дженериков этого...

Ответ 7

Что значит "без итерации"?

Вы можете использовать map.entrySet().iterator().next(), и вы не будете перебирать по карте (в смысле "касаться каждого объекта" ). Однако вы не можете получить Entry<K, V> без использования итератора. Javadoc Map.Entry говорит:

Метод Map.entrySet возвращает сборный вид карты, чья элементы этого класса. Единственный способ получить ссылку на карту запись из итератора этого Коллекция ракурса. Эти Map.Entry объекты действительны только для продолжительность итерации.

Можете ли вы объяснить более подробно, что вы пытаетесь выполнить? Если вы хотите сначала обрабатывать объекты, которые соответствуют определенному критерию (например, "иметь конкретный ключ" ) и в противном случае возвращаются к остальным объектам, посмотрите на PriorityQueue. Он будет заказывать ваши объекты на основе естественного порядка или настраиваемого пользователем Comparator, который вы предоставляете.

Ответ 8

import java.util.*;

public class Friday {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<String, Integer>();

        map.put("code", 10);
        map.put("to", 11);
        map.put("joy", 12);

        if (! map.isEmpty()) {
            Map.Entry<String, Integer> entry = map.entrySet().iterator().next();
            System.out.println(entry);
        }
    }
}

Этот подход не работает, потому что вы использовали HashMap. Я предполагаю, что использование LinkedHashMap будет правильным решением в этом случае.

Ответ 9

Если вы используете Java 8, это так же просто, как findFirst():

Быстрый пример:

Optional<Car> theCarFoundOpt = carMap.values().stream().findFirst();

if(theCarFoundOpt.isPresent()) {
    theCarFoundOpt.get().startEngine();
}

Ответ 10

Это приведет к тому, что на карте появится одна запись, которая примерно так же близка, как и "первая".

import java.util.*;

public class Friday {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<String, Integer>();

        map.put("code", 10);
        map.put("to", 11);
        map.put("joy", 12);

        if (! map.isEmpty()) {
            Map.Entry<String, Integer> entry = map.entrySet().iterator().next();
            System.out.println(entry);
        }
    }
}

Ответ 11

Наткнулся на то, чтобы найти то же самое... Затем я вспомнил класс Iterables из библиотеки Guava.

Чтобы получить "первый" элемент: Iterables.getFirst( someMap.values(), null );.
По существу делает то же самое, что и Map.values().iterator().next(), но также позволяет указать значение по умолчанию (в данном случае значение null), если на карте не будет ничего.

Iterables.getLast( someMap.values(), null ); возвращает последний элемент на карте.

Iterables.get( someMap.values(), 7, null ); возвращает 7-й элемент в Map, если существует, в противном случае значение по умолчанию (в данном случае null).

Помните, что HashMaps не упорядочены... так что не ожидайте, что Iterables.getFirst вернет первый элемент, который вы там бросили... аналогично с Iterables.getLast. Возможно, полезно получить a.

Возможно, не стоит добавлять библиотеку Guava только для этого, но если вы используете некоторые другие полезные утилиты в этой библиотеке...

Ответ 12

Следуя вашему EDIT, здесь мое предложение:

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

  • массив (из 2 значений, ключа и значения)
  • простой объект с двумя свойствами

Ответ 13

Я получил ответ: (Это просто)

Возьмите ArrayList, затем бросьте его и найдите размер arraylist. Вот он:

    ArrayList count = new ArrayList();
    count=(ArrayList) maptabcolname.get("k1"); //here "k1" is Key
    System.out.println("number of elements="+count.size());

Он покажет размер. (Дайте предложение). Это работает.