我想从bean列表中的枚举属性列表中计算最高序数枚举值.
例如,我有:
@Data
public class MyBean {
private Priority priority;
}
Run Code Online (Sandbox Code Playgroud)
和
public enum Priority {
URGENT("Urgent"),
HIGH("High"),
MEDIUM("Medium"),
LOW("Low");
@Getter
private final String value;
Priority(String value) {
this.value = value;
}
@Override
public String toString() {
return getValue();
}
}
Run Code Online (Sandbox Code Playgroud)
如果我有一个List的MyBeans,我怎么能找到bean的的最大序号值priority列表中?
例:
{myBean1, myBean2, myBean3, myBean4} where
myBean1.getPriority() = Priority.LOW
myBean2.getPriority() = Priority.URGENT
myBean3.getPriority() = Priority.HIGH
myBean4.getPriority() = null
returns Priority.URGENT
Run Code Online (Sandbox Code Playgroud)
我认为最糟糕的情况是我可以values()在枚举中迭代Collections.min(Arrays.asList(Priority.values()));并循环遍历每个bean以查看值是否匹配.但这似乎很乏味.
您可以使用Stream API,尤其是max(Comparator)方法来查找具有最高优先级的bean.
注意:您的枚举具有反向顺序的优先级.在我的例子中,我将假设相反的方式使代码更加不言自明.切换max为min与nullsFirst同nullsLast,如果不重新安排你的枚举.
Bean highest = beans.stream()
.max(Comparator.comparing(Bean::getPriority,
Comparator.nullsFirst(Comparator.comparing(Priority::ordinal))))
.orElse(null);
return highest.getPriority();
Run Code Online (Sandbox Code Playgroud)
如果您只需要优先级,则可以简化:
return beans.stream()
.map(Bean::getPriority)
.filter(Objects::nonNull)
.max(Comparator.comparing(Enum::ordinal))
.orElse(null);
Run Code Online (Sandbox Code Playgroud)
它的工作原理如下:
注意:我的例子非常详细.shmosel(删除)的答案表明你可以自然地订购枚举ordinal,制作更好的比较器. Comparator.comparing(Enum::ordinal)可以成为Comparator.naturalOrder().
我会给每个优先级一个特定的数值并添加一个可以比较它们的方法。不幸的是,枚举不能实现 Comparable(为了一致性),这在这里有点令人失望。
您返回空标记值的事实使事情稍微复杂化。如果我是你,我会重新考虑这一点。考虑一个“默认”优先级,如果缺少一个,它可以作为我们的优先级。
我已将默认优先级添加为一个完全独特的选项,但根据您的需要,您可以使用中或低作为默认值。
public enum Priority {
URGENT ("Urgent", 10),
HIGH ("High", 5),
MEDIUM ("Medium", 2),
LOW ("Low", 0),
DEFAULT("Default",-1);
@Getter
private final String name;
private final int value;
Priority(String name, int value) {
this.name = name;
this.value = value;
}
@Override
public String toString() {
return getName();
}
public int compare(Priority that) {
return Integer.compare(this.value, that.value);
}
}
Run Code Online (Sandbox Code Playgroud)
然后你需要改变你的优先级 getter 来返回这个新的默认值而不是null,否则我们稍后会得到空指针异常。
public class MyBean {
private Priority priority;
// Never returns null :)
public Priority getPriority() {
return (priority != null) ? priority : Priority.DEFAULT;
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们已经完成了“艰苦”的工作,获得最高优先级非常容易:
Priority max = Collections.max(beans, (a,b) ->
a.getPriority().compare(b.getPriority())
).getPriority();
Run Code Online (Sandbox Code Playgroud)