Как убрать дубликаты максимума и минимума за один стрим
Я хочу удалить только дубликаты максимальных и минимальных значений из набора целых чисел, возможно ли сделать за один стрим.
IntSummaryStatistics stats = values.stream()
.mapToInt(Integer::intValue)
.summaryStatistics();
List<Integer> collection = values.stream()
.filter(integer -> integer > stats.getMin() && integer < stats.getMax())
.collect(Collectors.toList());
collection.add(stats.getMax());
collection.add(stats.getMin());
Ответы (1 шт):
Автор решения: Nowhere Man
→ Ссылка
Существующий функционал стримов не слишком подходит, понадобится написать собственный коллектор в объект наподобие IntSummaryStatistics, в котором следовало бы "собирать" списки максимумов, минимумов и промежуточных значений по отдельности, и затем объединить такие списки.
Проще решить такую задачу в общем случае, когда исходный набор чисел не отсортирован, за один проход (при этом первоначальный порядок чисел в результате не гарантируется):
static <T extends Comparable<T>> List<T> filterDupMinMax(Collection<T> data) {
List<T> mins = new ArrayList<>();
List<T> maxs = new ArrayList<>();
List<T> mids = new ArrayList<>();
T min = null;
T max = null;
for (T n : data) {
if (null == min) {
min = n;
mins.add(n);
} else if (min.compareTo(n) >= 0) {
if (min.compareTo(n) > 0) {
if (null == max) {
max = min;
maxs.add(min);
} else {
mids.addAll(mins);
}
mins.clear();
min = n;
}
mins.add(n);
} else {
if (null == max) {
max = n;
maxs.add(n);
} else if (max.compareTo(n) <= 0) {
if (max.compareTo(n) < 0) {
mids.addAll(maxs);
maxs.clear();
max = n;
}
maxs.add(n);
} else {
mids.add(n);
}
}
}
// отладочный вывод
System.out.println("mins=" + mins);
System.out.println("maxs=" + maxs);
System.out.println("mids=" + mids);
List<T> result = new ArrayList<>(mids);
if (!mins.isEmpty()) result.add(mins.get(0));
if (!maxs.isEmpty()) result.add(maxs.get(0));
return result;
}
Тест:
List<Integer> data = Arrays.asList(4, 2, 5, 5, 3, 1, 2, 1, 5);
System.out.println("result: " + filterDupMinMax(data));
Результат:
mins=[1, 1]
maxs=[5, 5, 5]
mids=[4, 3, 2, 2]
result: [4, 3, 2, 2, 1, 5]