Как получить из структуры данных строку в отсортированном виде без повторений и с элементами больше трех, используя Stream в Java?
Что проверяют
Умеете ли вы собрать цепочку из нескольких промежуточных операций в правильном порядке и понимаете, что делает каждая. Формулировка «больше трёх» двусмысленна, и уточнить её вслух уже часть ответа. Следом просят поменять порядок сортировки или сделать то же для массива int[].
Как отвечать
Сначала уточните условие: числа больше 3 или строки длиннее трёх символов. Для списка чисел:
String result = numbers.stream()
.filter(n -> n > 3)
.distinct()
.sorted()
.map(String::valueOf)
.collect(Collectors.joining(", "));Для строк фильтр меняется на s -> s.length() > 3, остальное то же. Для int[] поток примитивный: Arrays.stream(arr), затем те же filter, distinct, sorted и mapToObj(String::valueOf), иначе joining не собрать.
Что стоит проговорить:
- порядок операций:
filterставят первым, он уменьшает объём дляdistinctиsorted, которые держат элементы в памяти; distinct(): сравнивает черезequalsиhashCode. Для своих классов без этих методов дубликаты не уберутся;sorted(): естественный порядок. Для обратного естьsorted(Comparator.reverseOrder());Collectors.joining: принимает разделитель, а также префикс и суффикс, напримерjoining(", ", "[", "]");- альтернатива:
Collectors.toCollection(TreeSet::new)убирает дубликаты и сортирует за один шаг, но строку потом всё равно придётся склеить.
Сложность определяется сортировкой, это O(n log n), а distinct на хэшах в среднем линейный.
Где спотыкаются
Переводят числа в строки до сортировки. Порядок становится лексикографическим, и 10 оказывается раньше 4. Преобразование в строку ставят последним шагом перед joining.
Забывают, что sorted() сравнивает строки по кодам символов: заглавные буквы идут раньше строчных, а «ё» уезжает в конец алфавита. Для человеческого порядка нужен String.CASE_INSENSITIVE_ORDER или Collator для нужной локали.
Не думают про null в исходном списке. На n -> n > 3 распаковка Integer бросит NullPointerException, поэтому filter(Objects::nonNull) ставят в начало цепочки.