2015-08-17 4 views
12

Java 8 введен новый способ, чтобы получить параллельную реализацию SetConcurrentHashMap.newKeySet() против Collections.newSetFromMap()

// Pre-Java-8 way to create a concurrent set 
Set<String> oldStyle = Collections.newSetFromMap(new ConcurrentHashMap<>()); 
// New method in Java 8 
Set<String> newStyle = ConcurrentHashMap.newKeySet(); 

Есть ли причина предпочесть новый метод?

Любые преимущества/недостатки?

+8

Это короче ... – Reimeus

ответ

5

ConcurrentHashMap.newKeySet() должен быть несколько более эффективным, поскольку удаляет один уровень косвенности. Collections.newSetFromMap(map) в основном основан на перенаправлении операций на map.keySet(), но ConcurrentHashMap.newKeySet() очень близко к map.keySet() (только с поддержкой дополнений).

Что касается функциональности, я не вижу разницы.

+1

* «просто с поддержкой модификаций» * означает возможность * добавить *? Поскольку у наборов ключей всегда была возможность удалить поддержку. – dhke

+1

@dhke, обновлено, спасибо. –

+0

'как удаляет один уровень косвенности' - вы уверены? Как я вижу, KeySetView по-прежнему делегирует свой метод внутренней карте. – turbanoff

12

ConcurrentHashMap.newKeySet() является лишь частью функции, которая намного шире, чем Collections.newSetFromMap(new ConcurrentHashMap<>()).

Разница становится ясным, если вы посмотрите на этот пример:

Set<String> set=new ConcurrentHashMap<String,String>().keySet("hello"); 

Вместо отображения на Boolean.TRUE теперь вы добавив значение "hello" при добавлении нового значения в Set.

Именно поэтому возвращенные Set s имеют тип ConcurrentHashMap.KeySetView. Этот тип имеет дополнительные методы для asking for the backing map, а также which value will be used when adding new keys.


ConcurrentHashMap.newKeySet() Таким образом, хотя выглядит как делать то же самое, как Collections.newSetFromMap(new ConcurrentHashMap<>()), есть смысловая разница, что последний говорит, что вы не должны использовать карту после этого в то время как первое является частью функции, которая предназначена для взаимодействия с карта.

См Collections.newSetFromMap:

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

На самом деле, это даже не указано, что Collections.newSetFromMap будет использовать Boolean.TRUE для добавленных стоимостей, вы никогда не должны иметь дело с этим в любом случае ...


Это также может быть полезно, если вы тусклый пройти Set для кода, который явно запрашивает ConcurrentHashMap.KeySetView.


Если вы используете результат, используя время компиляции типа Set только, есть еще вероятность того, что код, который получает то, что Set будет использовать instanceof/типа приведения, чтобы узнать, что результат ConcurrentHashMap.newKeySet() поддерживаются a ConcurrentHashMap, в то время как результат Collections.newSetFromMap не скажет вам. С другой стороны, это также позволяет коду делать непреднамеренные вещи с помощью такой карты ...

+2

Хотя это правда, я не вижу, как эта функция может быть полезна с помощью 'ConcurrentHashMap.newKeySet()' ... –

+1

@ Тагир Валеев: Я добавил примечание, которое должно быть понятным. – Holger

 Смежные вопросы

  • Нет связанных вопросов^_^