Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
返回列表<;整数>;Java8中的from方法?_Java_Java 8_Java Stream - Fatal编程技术网

返回列表<;整数>;Java8中的from方法?

返回列表<;整数>;Java8中的from方法?,java,java-8,java-stream,Java,Java 8,Java Stream,我有以下方法(见下文)。代码正在运行,但我得到的提示是有很多重复,我应该使用IntStream 您能否指定如何更好地优化代码?提前谢谢 public static List<Integer> oddOrEven(List<Integer> integers) { long sum = integers.stream().mapToInt(i ->i).summaryStatistics().getSum(); if (sum % 2 == 0) {

我有以下方法(见下文)。代码正在运行,但我得到的提示是有很多重复,我应该使用
IntStream

您能否指定如何更好地优化代码?提前谢谢

public static List<Integer> oddOrEven(List<Integer> integers) {
    long sum = integers.stream().mapToInt(i ->i).summaryStatistics().getSum();
    if (sum % 2 == 0) {
        return integers.stream().filter(x -> x % 2==0).distinct().collect(Collectors.toList());
    } else if (sum % 2 != 0) {
        return integers.stream().filter(x -> x % 2 != 0).distinct().collect(Collectors.toList());
    }
    return null;
}
公共静态列表oddOrEven(列表整数){
long sum=integers.stream().mapToInt(i->i.summaryStatistics().getSum();
如果(总和%2==0){
返回integers.stream().filter(x->x%2==0.distinct().collect(Collectors.toList());
}否则如果(总和%2!=0){
返回整数.stream().filter(x->x%2!=0).distinct().collect(Collectors.toList());
}
返回null;
}

看起来您只需要元素的总和就可以检查它是奇数还是偶数。要知道这一点,检查奇数元素的数量是奇数还是偶数就足够了

您可以将输入拆分为奇数和偶数列表,并根据奇数
列表的大小决定返回哪一个:

public static List<Integer> oddOrEven(List<Integer> integers) {
    Map<Boolean,List<Integer>> 
        oddsAndEvens = integers.stream()
                               .collect(Collectors.partitioningBy(i->i%2==0));
    return oddsAndEvens.get(false).size() % 2 == 0 ? // check if there's an even number of odd
                                                     // elements, which means the sum is even
           oddsAndEvens.get(true) : // return the even elements
           oddsAndEvens.get(false); // return the odd elements
}
输出:

[1, 3, 5]
[2, 4]
编辑:

在我最初的回答中,我错过了
distinct()
步骤,该步骤应该在我们决定是否返回奇数或偶数元素之后执行。恐怕这需要添加第二个
管道:

public static List<Integer> oddOrEven(List<Integer> integers) {
    Map<Boolean,List<Integer>> 
        oddsAndEvens = integers.stream()
                               .collect(Collectors.partitioningBy(i->i%2==0));
    return oddsAndEvens.get(false).size() % 2 == 0 ?
           oddsAndEvens.get(true).stream().distinct().collect(Collectors.toList()) :
           oddsAndEvens.get(false).stream().distinct().collect(Collectors.toList());
}
公共静态列表oddOrEven(列表整数){
地图
oddsAndEvens=整数。stream()
.collect(收集器.partitionby(i->i%2==0));
返回oddsAndEvens.get(false).size()%2==0?
oddsAndEvens.get(true).stream().distinct().collect(Collectors.toList()):
get(false).stream().distinct().collect(Collectors.toList());
}
或者(根据霍尔格的建议):

公共静态列表oddOrEven(列表整数){
地图
oddsAndEvens=整数。stream()
.collect(收集器.partitionby(i->i%2==0));
返回oddsAndEvens.get(oddsAndEvens.get(false).size()%2==0)
.stream()
.distinct()
.collect(Collectors.toList());
}
公共静态列表oddOrEven(列表整数){
函数fun=i->i%2;
Map Map=integers.stream().collect(Collectors.groupingBy(fun));
返回map.get(1.size()%2==0?map.get(0):map.get(1);
}

我将为您提供一个更简单的解决方案,它使用标准java语言构造,而不创建流所创建的其他寄生虫对象。我不是说溪流不好。我想说的是,如果您将一个列表传递给一个方法并返回一个列表,那么转换为流并收集回列表是额外的工作,您不需要也不应该这样做。您可以出于教育目的尝试它,也可以学习流,但在这种特殊情况下,您只会失去性能,如果您在实际应用程序中的任何地方都这样做,它将累积起来,并可能成为一个重大问题。尽管过早优化不是一件好事,但同样可以说,使用流做任何事情都是因为它们在Java中,根本不关心性能

如果奇数是偶数,那么和也是偶数。下面是一些使用位运算符的代码(只是为了好玩-您可以使用标准i%2等编写):

公共静态集合oddOrEven(列表整数){
int mod=0;
for(整数i:整数){
如果((i&1)=1)模=模^1;
}
Set result=new HashSet();
for(整数i:整数){
如果(((i&1)^mod)==0)
结果.添加(i);
}
return result;//正在转换为set,因为我们需要不同的结果。
//如果顺序很重要,我们可以使用树集或转换为列表
}

您可以对其他基于流的解决方案进行一些测试。在大多数情况下,使用标准java构造而没有额外重载的解决方案将具有相同的速度或更快的速度。例如,使用map很好,但是如果列表较大,在某个点上有大量重复的数字,那么碰撞的数量会使它比其他方法慢很多倍。所有算法的复杂度都是线性的,但一次迭代的工作量会随着不同的流解决方案(以及老式方法)而变化如果你不知道损失是什么,那么坚持众所周知且易于预测的方案可能会更好。

关于工作代码的问题属于我。我对
IntStream
部分感兴趣。如果你收到一个整数列表,为什么会有人强调它?它更适合于从无到有创建流。您只需使用
sum()
而不是
.summaryStatistics().getSum()
。此外,
如果(总和%2!=0)
已过时,则条件必须为
true
。当您删除它时,您可以删除无法访问的
returnnull也是。除此之外,您正在使用
mapToInt
,因此您正在使用
IntStream
。非常感谢。这是一个包裹!)如果列表中包含负数,则此操作无效。例如,尝试使用oddOrEven(Arrays.asList(1,-2))
。是的,需要一个abs()或者像(x&1)=(sum&1)@Floegipoky这样的位检查。我错过了OP代码中的distinct()调用。谢谢你指出这一点。稍后我将修改答案。为什么不
返回oddsAndEvens.get(oddsAndEvens.get(false).size()%2==0)
?@Holger nice Improvement因此,您可以使用collector.toSet,也可以使用order Collectors.toCollection(LinkedHashSet::new),而不是收集到要设置的不同项(这将使方法的使用者更容易知道只有不同项)。这只是一个想法;)事实上,你正在变得比线性缩放更好,这表明你的基准是有缺陷的。此外,您正在忽略流解决方案的
distinct()
方面,因此结果无论如何都是不可比较的
public static List<Integer> oddOrEven(List<Integer> integers) {
    Map<Boolean,List<Integer>> 
        oddsAndEvens = integers.stream()
                               .collect(Collectors.partitioningBy(i->i%2==0));
    return oddsAndEvens.get(false).size() % 2 == 0 ?
           oddsAndEvens.get(true).stream().distinct().collect(Collectors.toList()) :
           oddsAndEvens.get(false).stream().distinct().collect(Collectors.toList());
}
public static List<Integer> oddOrEven(List<Integer> integers) {
    Map<Boolean,List<Integer>> 
        oddsAndEvens = integers.stream()
                               .collect(Collectors.partitioningBy(i->i%2==0));
    return oddsAndEvens.get(oddsAndEvens.get(false).size() % 2 == 0)
                       .stream()
                       .distinct()
                       .collect(Collectors.toList());
}
 long sum = integers.stream().reduce(0, (u, v) -> u + v);
 return integers.stream().filter(x -> (x % 2)==(sum % 2)).distinct().collect(Collectors.toList());
public static List<Integer> oddOrEven(List<Integer> integers) {
    Function<Integer, Integer> fun =  i -> i%2;
    Map<Integer, List<Integer>> map = integers.stream().collect(Collectors.groupingBy(fun));        
    return map.get(1).size()%2 == 0? map.get(0): map.get(1);
}
public static Collection<Integer> oddOrEven(List<Integer> integers) {
    int mod = 0;
    for (Integer i : integers) {
        if((i & 1) == 1) mod=mod^1;
    }
    Set<Integer> result = new HashSet<>();
    for (Integer i : integers){
        if (((i & 1) ^ mod)==0)     
           result.add(i);

      }
  return result; //Converting to set because we want distinct results.
                 // If the order is important we can use treeset or convert to list
}