Отдельные элементы Список, Набор, HashSet, Лямбда, Java 8 - PullRequest
0 голосов
/ 02 октября 2019

У меня есть три варианта, чтобы получить Отдельные предметы в List

return new ArrayList<>(new HashSet<>(someTypeList));

return new HashSet<>(someTypeList).stream().collect(Collectors.toList());

return someTypeList.stream().collect(Collectors.toSet()).stream().collect(Collectors.toList());

Какой вариант вы мне порекомендуете и почему?

И еслисуществует какая-то единственная альтернатива, пожалуйста, скажите мне.

Ответы [ 2 ]

1 голос
/ 02 октября 2019

Вы должны быть последовательными и не смешивать разные подходы.

Существует подход API Collection, использующий либо

  • new ArrayList<>(new HashSet<>(someTypeList)), либо
  • new ArrayList<>(new LinkedHashSet<>(someTypeList)), когда выхотите сохранить порядок

Тогда есть подход Stream API

  • someTypeList.stream().distinct().collect(Collectors.toList()); или
  • someTypeList.stream().distinct().collect(Collectors.toCollection(ArrayList::new));
    , когда вам нужнов результате получается ArrayList

Когда someTypeList является обычной реализацией List, подход Collection не только проще, но и более эффективен. API-интерфейс Stream в любом случае использует HashSet при реализации distinct(), но операция collect немного пострадает от абстракции, так как не имеет подсказки об ожидаемом количестве элементов. Напротив, конструктор ArrayList будет просто вызывать toArray для входящего HashSet и использовать результат в качестве своего резервного массива.

Все меняется, когда someTypeList является неизвестной коллекцией. В некоторых сценариях Stream API может использовать характеристики источника для оптимизации операции. Если в источнике уже есть отдельные элементы, например, с Set, накладные расходы на distinct() будут устранены. Если источник отсортирован, для идентификации дубликатов будет использоваться другой алгоритм, для которого не требуется HashSet.

Поскольку Stream API инкапсулирует фактическую реализацию, он может получить будущие улучшения без необходимостиадаптировать клиентский код. Напротив, явная операция Collection всегда будет делать именно то, что ей было сказано, никогда не получая выгоды от альтернативных стратегий реализации.

1 голос
/ 02 октября 2019
  • Первый вариант не сохраняет первоначальный порядок списка, а также должен создавать набор, а затем копировать в список.
  • Первый вариант лучше второго, так как поток будет иметь снижение производительности.
  • Лучше, чем 3-й вариант, someTypeList.stream().distinct().collect(Collectors.toList())

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

например Guava ImmutableSet

ImmutableSet.copyOf(listInts).asList();

Надеюсь, это поможет.

...