Неожиданный вывод с HashMap - PullRequest
3 голосов
/ 16 марта 2011

КОД:

public class Puzzle23{
    void Puzzle23(){
        map1.put(String1, "1");
        map1.put(String2, "2");
    }

    private final NewMap map1 = new NewMap();
    private static final String String1 = new String("J2eeSig");
    private static final String String2 = new String("J2eeSig");

    public static void main(final String args[]){
        final Puzzle23 p22 = new Puzzle23();
        final Map<String, String> map2 = new HashMap();

        map2.put(String1, "1");
        map2.put(String2, "2");
        System.out.println(p22.map1.size() == map2.size() ? true : false);
        p22.map1.remove(new String(String1));
        map2.remove(new String(String2));
        System.out.println(p22.map1.size() == map2.size() ? true : false);
    }

    class NewMap extends IdentityHashMap<String, String>{
        public void put(final String... values){
            super.put(values[0], values[1]);
        }

        public int size(){
            return super.size() + 1 - 1 / 1 * 1;
        }
    }
}

Фактический результат: -

false
true

Ожидаемый результат: -

true
true

Почему ???

Ответы [ 3 ]

6 голосов
/ 16 марта 2011

это из-за использования NewMap это IdentityHashMap.Проверьте документацию, где сказано

Этот класс не является реализацией Map общего назначения!Хотя этот класс реализует интерфейс Map, он намеренно нарушает общий контракт Map, который обязывает использовать метод equals при сравнении объектов.Этот класс предназначен для использования только в тех редких случаях, когда требуется семантика равенства ссылок.

РЕДАКТИРОВАТЬ: В любом случае я нашел ошибку в вашем коде.void Puzzle23() это не конструктор, это метод.Конструктор должен быть определен без возвращаемого значения (например, Puzzle23()).Таким образом, вы никогда не заполните map1.Когда вы исправите это, вы поймете, что ваш вывод false false из-за IdentityHashMap.При переключении map1 на HashMap вывод будет true true, как и ожидалось.В любом случае проверьте документацию IdentityHashMap.

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

IdentityHashMap использует ==, где обычный HashMap использует .equals().См. документацию .

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

p22.map1.remove(new String(String1)); ничего не удалит, потому что NewMap является подклассом IdentityHashMap.

Обновление

Я был не прав

1) Первая ошибка здесь - это метод void, замаскированный под конструктор. Вот почему p22.map1 всегда пусто.

2) Вторым является NewMap, что IdentityHashMap. После того, как к нему добавлено 2 строки, его размер становится равным 2, поскольку, хотя эти строки равны, они не идентичны (==).

3) p22.map1.remove(new String(String1)); не будет ничего делать, как я говорил ранее.

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