2014-12-20 6 views
3

У меня есть HashMap<Foo,ArrayList<Bar>>, и я хочу, чтобы когда я получил ArrayList, связанный с ключом, и добавил к нему какое-то значение.Тройной оператор, выполняющий методы

Тройная оператор делает

То, что я сейчас делаю это проверка, если значение, связанное с ключом Foo является недействительным, если после этого сделать новый ArrayList добавить, что я хочу его и положил его обратно в карта. Если нет, я сохраняю, что arrayList добавляет то, что я хочу к нему, и снова помещаю его обратно в карту.

я мог бы сделать это следующим образом:

ArrayList<Bar> valuesList = map.get(key); 
if(valuesList == null){ 
    valuesList = new ArrayList<Bar>; 
} 
valuesList.add(Item); 
map.put(Foo,valuesList); 

Но я предпочитаю использовать тройной оператор, чтобы мой код немного короче:

ArrayList<Bar> valuesList= (map.get(key) == null) ? new ArrayList<Bar>() : map.get(key); 
valuesList.add(Item); 
map.put(Foo,valuesList); 

Мой вопрос (во втором) пример я выполняю map.get(key) дважды? Или компилятор Java умеет и оценивает его только один раз? (Я знаю, что это крошечная разница в скорости выполнения, но если она выполняется дважды, для меня достаточно причины, чтобы я начал использовать пример 1)

+0

Использование гуавы MultiMap вместо: https://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multimap – eiden

+0

вы могли бы исследовать байткод с помощью 'javap -c com.mypackage.MyClass', чтобы посмотреть, что происходит под капотом. – wvdz

+0

Итак, вместо использования временной переменной для результата 'map.get (key)', вы скорее всего используете первый код вместо предпочитаемого трехмерного оператора? – Tom

ответ

3

Следующее - то, что я использовал бы, так как вы также не стали бы излишне позвонить пута, если список уже в вашей карте:

List<Bar> valuesList = map.get(key); 
if(valuesList == null){ 
    valuesList = new ArrayList<Bar>(); 
    map.put(key,valuesList); 
} 
valuesList.add(Item); 

Обратите внимание, я нахожу это гораздо более читабельным, чем при использовании тройной оператор (меньше строк кода не обязательно проще, имхо). И в зависимости от размера ваших карт, сохранение ненужных вызовов (get и put) не может быть тривиальным.

2

Исследование байт-кода узнает, что метод get() фактически вызывается дважды во втором фрагменте кода. Теоретически возможно, что карта будет меняться между вызовами, поэтому это невозможно оптимизировать.

На боковой ноте: ваш вызов map.put() избыточен, потому что, изменяя объект, вы автоматически меняете сохраненный объект на карте. Вы не вытаскиваете копию с карты, вы тянете ссылку на объект с карты.

1

Почему бы не передать map.get (key) в переменной, а затем использовать его с тройным оператором?

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

Object value = map.get(key); 
ArrayList<Bar> valuesList = (value == null) ? new ArrayList<Bar>() : value; 
valuesList.add(Item); 
map.put(Foo,valuesList); 
Смежные вопросы