9

我对使用来自 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

有额外的排序,因为我们可以有 shuiffed 列表。

4

2 回答 2

27

别忘了Collection.removeIf。您可以计算最小值和最大值,然后执行以下操作:

list.removeIf(x -> x == min || x == max);

(这也很好地处理了重复。)

于 2014-07-10T15:54:11.037 回答
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 甚至更快排序 - 遍历所有元素,找到最小值和最大值,记住它们的位置,然后删除它们。

于 2014-04-07T21:26:53.883 回答