Подтвердить что ты не робот

Итерирование по набору карт

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

При повторении такого набора записей, почему это не компилируется?

public void myMethod(Map anyMap) {
    for(Entry entry : anyMap.entrySet()) {
        ...
    }
}

но этот компилятор:

public void myMethod(Map anyMap) {
    Set<Entry> entries = anyMap.entrySet();
    for(Entry entry : entries) {
        ...
    }
}

и это также компилируется (я не могу использовать этот, так как я не знаю типы карты):

public void myMethod(Map<String, String> stringMap) {
    for(Entry<String,String> entry : stringMap.entrySet()) {
        ...
    }
}
4b9b3361

Ответ 1

Ошибка, которую вы получите в первой:

Type mismatch: cannot convert from element type Object to Map.Entry

Это связано с тем, что компилятор преобразует ваш цикл FOR-IN:

for (Entry entry : anyMap.entrySet()) {
}

To:

for (Iterator i = anyMap.entrySet().iterator(); i.hasNext();) {
    Entry e = i.next(); // not allowed
}

Второй пример работает, , но только путем обмана!. Вы делаете неконтролируемый актерский состав, чтобы получить Set обратно в Set<Entry>.

Set<Entry> entries = anyMap.entrySet(); // you get a compiler warning here
for (Entry entry : entries) {
}

становится:

Set<Entry> entries = anyMap.entrySet();
for (Iterator<Entry> i = entries.iterator(); i.hasNext(); ) {
    Entry e = (Entry) i.next(); // allowed
}

Обновление

Как упоминалось в комментариях, информация о типе теряется в обоих примерах: из-за правил стирания исходного типа компилятора.

Чтобы обеспечить обратную совместимость, методы ВСЕ экземпляров необработанных типов заменяются их удаляемыми аналогами. Итак, поскольку ваш Map является сырым типом, все его стирается. Включая его метод Set<Map.Entry<K, V>> entrySet();: ваш экземпляр типа raw будет вынужден использовать стертую версию: Set entrySet().

Ответ 2

Это связано с тем, что вы используете карту исходного типа, поэтому map.entrySet() получает вам непараметризованный набор, который в результате возвращает Object на итерации, а не в Entry.

Простым, но изящным решением является использование Map <?,? > , которое все равно позволит вам передавать ЛЮБОЮ карту, но с другой стороны вынуждает map.entrySet() иметь возвращаемое значение Set <Entry> ;

public void test(Map<?,?> map) {        
    for(Entry e : map.entrySet()){
        Object key = e.getKey();
        Object value = e.getValue();
    }       
}

Ответ 3

В первом примере map.entrySet() возвращает Set, когда вы повторяете цикл, вы используете Iterator. Нет информации о заданном типе контента, поэтому Java использует Object as Object как базовый тип, а компилятор сообщает вам, что он не может преобразовать Object to Entry.

Set<Map.Entry<K, V>> entrySet();

Когда вы используете тип сырой карты, entrySet возвращает только Set, без информации о типе.

Во втором примере вы вручную конвертируете Set to Set <Entry> (с предупреждением). Теперь Java знает, что внутри. Таким образом, вы можете выполнять итерацию.

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

Ответ 4

первый фрагмент кода не будет компилироваться, потому что переменная map не существует. Вы вызвали параметр anyMap, но попытались получить к нему доступ в качестве map, исправить это, и ваш код будет компилироваться в сторону от некоторых предупреждений типа rawtypes

Ответ 5

Вы получаете время компиляции rrror, потому что вы не указываете тип в HashMap

Как

HashMap <(Integer,String> hm=new HashMap<(Integer,String>();  

Если вы укажете тип как Integer и String, вы не получите ошибку времени компиляции.

ЕСЛИ вы не знаете, какое значение будет добавлено в ваш HashMap, а затем вы используете

HashMap < (Object, Object > hm = new HashMap();

Ответ 6

Я столкнулся с той же проблемой. Кажется, что кастинг - это проблема. Я попробовал приведенный ниже код, и он сработал.

    for(Object entry : hashMap.entrySet())
    {
        System.out.println(((Entry<Object, Object>) entry).getKey() + " = " + ((Entry<Object, Object>) entry).getValue());

    }