我对使用Java 8中的新流API的代码设计没有什么问题。我想学习新的东西,其中一项任务是:
拒绝列表中的最大值和最小值。列表不包含重复项。
看起来很简单?不......我的代码:
List<Integer> ranges = Lists.newArrayList(new Range(1, 15));
List<Integer> collect = ranges.stream()
.filter(x -> x != ranges.stream()
.mapToInt(Integer::intValue)
.max()
.getAsInt())
.filter(x -> x != ranges.stream()
.mapToInt(Integer::intValue)
.min()
.getAsInt())
.collect(Collectors.toList());
assertThat(collect).hasSize(13); // OK
assertThat(collect).isEqualTo(Lists.newArrayList(new Range(2,14))); // OK
这段代码很好(如果我们没有min / max的重复,但这不是核心问题)但问题是我在这里使用了三个流。首先是主流,第二个是删除最大值,第三个是删除最小值。 是否有可能在一个流中执行此任务?
//编辑: 非常原始的Scala版本:
val list = List.range(1, 15).sortWith(_>_).tail.reverse.tail
另外排序,因为我们可以有shuiffeled list。
答案 0 :(得分:25)
别忘了Collection.removeIf
。您可以计算最小值和最大值,然后执行:
list.removeIf(x -> x == min || x == max);
(这也适用于重复。)
答案 1 :(得分:6)
解决方案效率不高,但我认为它符合您的要求 - 它可以满足您的需求,并且只需一个管道 - 一个批量数据操作序列,Java 8如何调用它
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Stream<Integer> ranges = Stream.iterate(1, i -> i + 1).limit(15);
List<Integer> collect = ranges
.sorted(Comparator.reverseOrder()) // sort the stream from the highest to the smallest
.skip(1) // discards 1 element from the beginning
.sorted() // sort the stream from the smallest to the highest
.skip(1) // discards 1 element from the beginning
.collect(Collectors.toList())
;
但是,正如fge所建议的那样,Marco13在你的问题下面的评论中写道,对流进行排序,将管道终止到列表然后删除第一个和最后一个成员会更好更高效:P或更快,没有排序 - 浏览所有元素,找到最小值和最大值,记住它们的位置,然后将它们删除。