使用Java 8 Stream API按范围分组

huangapple go评论74阅读模式
英文:

Grouping by ranges with Java 8 Stream API

问题

以下是您要求的翻译内容:

正如标题所示,我正在尝试使用 groupingBy 来根据它们的“能量级别”范围对对象列表进行分组。我对 Java Stream API 还非常陌生,所以我不太了解其中的操作方式。我编写的代码无法编译,我不确定原因是什么,我觉得我有正确的想法,但它没有起作用。任何帮助将不胜感激!您可以在下面找到我的尝试代码。

以下是我的 groupingBy 尝试:

Map<BigDecimal, List<Employee>> ranges = ObjectList.stream()
        .collect(Collectors.groupingBy(a -> {
            if(a.powerLevel < 2500) { a.powerLevel = LOWER;}
            else if(a.powerLevel > 10000) {a.powerLevel = UPPER;}
            else {a.powerLevel = MIDDLE;}
        }
));

以下是我的枚举类:

enum salaryRanges { 
    LOWER, MIDDLE, UPPER
}   

附注:我尝试过是否可以创建一个具有范围的枚举类,但根据我阅读的内容,在 Java 中这是不可能的。

英文:

As the title implies, I am trying to is groupingBy to group a list of objects by range of their "power levels". I am very new to Java Stream API, so I don't quite know my way around it. The code I have written won't compile and I'm just not certain why, I think I have the right idea, but it's not working. Any help would be greatly appreciated! You can find my failed attempt below.

This is the groupingBy attempt:

Map&lt;BigDecimal, List&lt;Employee&gt;&gt; ranges = ObjectList.stream()
        .collect(Collectors.groupingBy(a -&gt; {
            if(a.powerLevel &lt; 2500) { a.powerLevel = LOWER;}
            else if(a.powerLevel &gt;10000) {a.powerLevel = UPPER;}
            else {a.PowerLevel = MIDDLE;}
        }
));

This is my enum:

enum salaryRanges { 
    LOWER, MIDDLE, UPPER
}   

PS:I tried to see if I could make an enum with ranges, but from what I've read that it not possible in Java.

答案1

得分: 2

我建议将逻辑移动到不同的方法中,用于定义范围

public static salaryRanges getRange(Employee employee) {
    if(employee.powerLevel < 2500){
        return salaryRanges.LOWER;
    }

    if(employee.powerLevel > 10000){
        return salaryRanges.UPPER;
    }

    return salaryRanges.MIDDLE;
}

然后使用 Collectors.groupingBy

Map<salaryRanges,List<Employee>> res = list.stream()
            .collect(Collectors.groupingBy(JavaMain::getRange));

您还可以像 @Andreas 建议的那样,通过将定义薪资范围逻辑移到枚举中来以另一种方式完成

enum salaryRanges {
    LOWER, MIDDLE, UPPER

    public static salaryRanges fromPowerLevel(int powerLevel){
        if(powerLevel < 2500){
            return salaryRanges.LOWER;
        }

        if(powerLevel > 10000){
            return salaryRanges.UPPER;
        }

        return salaryRanges.MIDDLE;
    }
}

然后使用 lambda 表达式调用该方法

Map<salaryRanges,List<Employee>> res = list.stream()
            .collect(Collectors.groupingBy(emp -> salaryRanges.fromPowerLevel(emp.powerLevel)));
英文:

I would recommended to move logic into different method that defines range

   public static salaryRanges getRange(Employee employee) {
    if(employee.powerLevel &lt; 2500){
        return salaryRanges.LOWER;
    }

    if(employee.powerLevel &gt; 10000){
        return salaryRanges.UPPER;
    }

    return salaryRanges.MIDDLE;
}

Then use Collectors.groupingBy

  Map&lt;salaryRanges,List&lt;Employee&gt;&gt; res = list.stream()
            .collect(Collectors.groupingBy(JavaMain::getRange));

You can also do it in another way as @Andreas suggested, by moving defining salary range logic into enum

enum salaryRanges {
LOWER, MIDDLE, UPPER

public static salaryRanges fromPowerLevel(int powerLevel){
    if(powerLevel&lt;2500){
        return salaryRanges.LOWER;
    }

    if(powerLevel&gt;10000){
        return salaryRanges.UPPER;
    }

    return salaryRanges.MIDDLE;
  }
}

And then calling that method using lambda expression

 Map&lt;salaryRanges,List&lt;Employee&gt;&gt; res = list.stream()
            .collect(Collectors.groupingBy(emp-&gt;salaryRanges.fromPowerLevel(emp.powerLevel)));

huangapple
  • 本文由 发表于 2020年9月23日 00:56:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/64014351.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定