Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Ассоциативный двумерный массив


Автор: Валерия 26.11.2014, 02:05
Код

HashMap<String, HashMap<String, String>> people = new HashMap<String, HashMap<String, String>>();
people.put("Vasia", new HashMap<>(Arrays.asList("Pupkin", "Designer")));
people.put("Petya", new HashMap<>(Arrays.asList("Ivanov", "Developer")));

Как правильно написать такое?
Я знаю что есть вариант написать вот так:
Код
HashMap<String, HashMap<String, String>> people = new HashMap<String, HashMap<String, String>>();

HashMap<String, String> my1 = new HashMap<String, String>();
my1.put("Pupkin", "Designer");

people.put("Vasia", my1);
        
HashMap<String, String> my2 = new HashMap<String, String>();
my2.put("Ivanov", "Developer");
people.put("Petya", my2);

Но не прикольно каждый раз создавать новый HashMap для каждого значения
Можно ли как-то это дело простым образом инициализировать?

Автор: sQu1rr 26.11.2014, 02:42
Есть как минимум три способа для автоматической инициализации мапа (не совсем точно отвечает на ваш вопрос, но доработать можно)
1. Вынесите в функцию и которая делает put и возвращает объект
Код

// ну тут ясно

2. Анонимный класс, но по моему слишком неоправданно
Код

HashMap<String, String > map = new HashMap<String, String>(){{
    put("Pupkin","Designer");
}};

3. https://code.google.com/p/guava-libraries/
Код

Map<String,String> map = ImmutableMap.of("Pupkin", "Designer", "Ivanov", "Developer");

Автор: Stolzen 26.11.2014, 10:09
Цитата(Валерия @  26.11.2014,  03:05 Найти цитируемый пост)
Можно ли как-то это дело простым образом инициализировать? 

Можно использовать Table из вышеупомянутой гуавы

Автор: Валерия 27.11.2014, 02:11
Всем спасибо smile
Но мне нужно стандартными средствами
Анонимный класс отлично подошел

Автор: sQu1rr 27.11.2014, 12:40
Цитата(Валерия @  27.11.2014,  00:11 Найти цитируемый пост)
Анонимный класс отлично подошел

А я бы все таки использовал функцию. Анониманый класс может сильно навредить, как производительности, так и читаемости кода

Автор: LSD 27.11.2014, 14:58
Цитата(sQu1rr @  27.11.2014,  13:40 Найти цитируемый пост)
Анониманый класс может сильно навредить, как производительности

Чем это?

Автор: sQu1rr 27.11.2014, 15:53
Цитата(LSD @  27.11.2014,  12:58 Найти цитируемый пост)
Чем это? 

Может тут ключевое слово. Создается внутренний анонимный класс, который держит указатель на внешний (Hashmap) класс. То есть еще один уровень индирекции, и кушается больше памяти, нет? Если таких объектов наклепать изрядно, то мусороуборке придется больше памяти очищать

Автор: LSD 27.11.2014, 16:28
Цитата(sQu1rr @  27.11.2014,  16:53 Найти цитируемый пост)
Может тут ключевое слово. Создается внутренний анонимный класс, который держит указатель на внешний (Hashmap) класс. То есть еще один уровень индирекции, и кушается больше памяти, нет? Если таких объектов наклепать изрядно, то мусороуборке придется больше памяти очищать 

Количество объектов подлежащих сборке это не изменит. Да и если бы изменило, то значительного влияния на производительность это не окажет.

Автор: sQu1rr 27.11.2014, 19:29
Цитата(LSD @  27.11.2014,  14:28 Найти цитируемый пост)
Количество объектов подлежащих сборке это не изменит

Кол-во какраз в 2 раза больше будет. Внутренний класс + внешний, вместо одного внешнего.

Цитата(LSD @  27.11.2014,  14:28 Найти цитируемый пост)
значительного влияния на производительность это не окажет

Цитата(sQu1rr @  27.11.2014,  13:53 Найти цитируемый пост)
Может тут ключевое слово

Да перестарался со словом сильно, извиняюсь

Автор: Валерия 27.11.2014, 20:11
Просто guava это не стандартные средства, а мне нужно сделать максимально стандартными средствами
Я просто сейчас учу Java и пишу на ней все те вещи которые мне нужны были в других ЯП, и вот ассоциативные массивы сделаны очень не удобно, по сравнению с php или perl, столько лишнего всего...

Автор: LSD 28.11.2014, 13:59
Цитата(sQu1rr @  27.11.2014,  20:29 Найти цитируемый пост)
Кол-во какраз в 2 раза больше будет. Внутренний класс + внешний, вместо одного внешнего.

Не понял откуда там 2 объекта.

Вариант 1:
Цитата(sQu1rr @  26.11.2014,  03:42 Найти цитируемый пост)
Вынесите в функцию и которая делает put и возвращает объект

1 - объект HashMap

Вариант 2
Цитата(sQu1rr @  26.11.2014,  03:42 Найти цитируемый пост)
Анонимный класс

1 - объект MyClass$1 extends HashMap

Автор: sQu1rr 28.11.2014, 14:29
А может я и туплю. нужно погуглить

Автор: sQu1rr 28.11.2014, 14:53
Вообщем. Нормализую ка я свою логику и попробую объяснится нормально, что я имел ввиду

Если вы делаете анонимный класс, он, и правда будет просто extend от родительского, НО будет содержать в себе ссылку на внешний класс (то есть тот класс в котором вы этот анонимный класс и создаете), а это значит, что этот внешний класс будет жить пока не умрет анонимный класс.
Код

class SomeClass {
    public returnOtherClass() {
        return OtherClass() { ... };
    }
}

Вернется анонимный экземпляр OtherClass который будет содержать ссылку на someClass, и если someClass выпадет из области видимости раньше чем anonOtherClass, то он не будет удалятся мусороуборкой, пока anonOtherClass не удалится. Вот. А про кол-во объектов я имел "за раз". Ну вы поняли.

Я очень хорошо в объяснениях я знаю

Автор: LSD 28.11.2014, 16:04
Цитата(sQu1rr @  28.11.2014,  15:53 Найти цитируемый пост)
Если вы делаете анонимный класс, он, и правда будет просто extend от родительского, НО будет содержать в себе ссылку на внешний класс

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

    public static void main(String[] args) throws Exception {
        Map<Integer, String> map = new HashMap<Integer, String>() {{
            put(1, "A");
            put(2, "B");
            put(3, "C");
        }};
        System.out.println(map);
    }

(хотя нас и пугают, что могут это убрать).

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)