所以,我有一个int[] arr,想用流求和,同时过滤掉最小的int。我得到了一个使用两个流的解决方案,它可以工作,但似乎没有效果。有什么方法可以只用一个流来实现吗?
代码是这样的。
int min = Arrays.stream(arr)
.min()
.getAsInt();
int sum = Arrays.stream(arr)
.filter(i -> i != min)
.sum();
int[] arr = {5, 4, 3, 2, 1};
int sumExcludingMin = Arrays.stream(arr)
.sorted()
.skip(1)
.reduce(0, Integer::sum); // or using lambda: reduce(0, (x,y) -> x+y)
// or specialized reduction form: sum()
这里,第一个参数是 reduce()
, 0
,身份元素既是还原的初始种子值,也是没有输入元素时的默认结果。
进一步阅读。
下面这段代码使用 IntSummaryStatistics 应该可以做到。
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6};
IntSummaryStatistics stats = Arrays.stream(arr).summaryStatistics();
int sum = (int) stats.getSum() - stats.getMin();
}
来自IntSummaryStatistics的文档。
一个用于收集统计数字的状态对象,如count, min, max, sum, and average.
...
...它在单次计算中,计算人的数量,以及他们的依赖者数量的最小、最大、总和和平均数。
EDIT: 如果你想删除所有有最小值的元素,
int[] arr = {1, 2, 3, 1, 1, 1};
TreeMap<Integer, Integer> map = Arrays.stream(arr).boxed()
.collect(toMap(
v -> v,
v -> 1,
Integer::sum,
TreeMap::new
));
map.remove(map.firstKey());
int sum = map.entrySet().stream().mapToInt(e -> e.getKey() * e.getValue()).sum();
System.out.println(sum);
或者
List<Integer> list = Arrays.stream(arr).sorted().boxed().collect(toList());
Integer min = list.get(0);
int sum2 = list.stream().mapToInt(i -> i).dropWhile(min::equals).sum();
System.out.println(sum2);
另一个技巧:不要使用并行流。它会给出错误的结果。它将表现良好.其线性0(n)
int[] min=new int[1];
min[0]=Integer.MAX_VALUE;
int sum = Arrays.stream(arr).map(x->{min[0]=Math.min(x,min[0]); return x;}).sum();
System.out.println(min[0]);
System.out.println(sum-min[0]); // can overflow!