Java 8 无法使用枚举筛选元素
我将ComputerComponent类的列表传递给averagePrice()函数,该函数有两个price字段 是双重和双重的类型 类型为字符串的类别 我的列表有4个元素,分类为“CPU”、“鼠标”, “键盘”和“存储”,价格分别为34.0、155.0、23.0和75.0 当我尝试使用inEnum()、isInEnum()或EnumUtils.isValidEnum()函数时,我得到了平均价格 作为34.0,我认为他们只是返回第一个元素的价格,而不是平均值Java 8 无法使用枚举筛选元素,java-8,enums,java-stream,Java 8,Enums,Java Stream,我将ComputerComponent类的列表传递给averagePrice()函数,该函数有两个price字段 是双重和双重的类型 类型为字符串的类别 我的列表有4个元素,分类为“CPU”、“鼠标”, “键盘”和“存储”,价格分别为34.0、155.0、23.0和75.0 当我尝试使用inEnum()、isInEnum()或EnumUtils.isValidEnum()函数时,我得到了平均价格 作为34.0,我认为他们只是返回第一个元素的价格,而不是平均值 protected static d
protected static double averagePrice( List<ComputerComponent> list ) {
return list.stream()
// .filter( line-> EnumUtils.isValidEnum(ComputerComponentCategory.class, line.getCategory()) )
// .filter( line-> isInEnum( line.getCategory(), ComputerComponentCategory.class) )
// .filter( line-> inEnum(line.getCategory(),EnumUtils.getEnumMap(ComputerComponentCategory.class ).keySet() ))
.filter( line ->
line.getCategory().contains("CPU")
|| line.getCategory().contains("GPU")
|| line.getCategory().contains("Monitor")
|| line.getCategory().contains("Keyboard")
|| line.getCategory().contains("Mouse")
|| line.getCategory().contains("Storage")
|| line.getCategory().contains("Memory"))
.mapToDouble(ComputerComponent::getPrice)
.average()
.orElseThrow(NoSuchElementException:: new);
}
我得到了正确的平均值71.75
我用于isInEnum()和inEnum()函数的实现如下:
But when I do filtering using
.filter( line ->
line.getCategory().contains("CPU")
|| line.getCategory().contains("GPU")
|| line.getCategory().contains("Monitor")
|| line.getCategory().contains("Keyboard")
|| line.getCategory().contains("Mouse")
|| line.getCategory().contains("Storage")
|| line.getCategory().contains("Memory"))
公共静态布尔值isInEnum(字符串值,类enumClass){
对于(E:enumClass.getEnumConstants()){
如果(e.name().contains(value)){return true;}
}
返回false;
}
公共静态布尔inEnum(字符串类别,设置值){
for(字符串s:值){
如果(类别包含){
返回true;
}
}
返回false;
}
如何在java streams中正确使用枚举来按有效的类别名称进行筛选并获得正确的
平均价格
使用streams及其函数时我犯了什么错误 您只需使用
ComputerCategoryValue.getValue方法,并根据行的类别检查null:
public static <E extends Enum<E>> boolean isInEnum(String value, Class<E> enumClass) {
for (E e : enumClass.getEnumConstants()) {
if(e.name().contains(value)) { return true; }
}
return false;
}
public static boolean inEnum ( String category, Set<String> value ) {
for(String s: value ) {
if ( category.contains(s) ) {
return true ;
}
}
return false ;
}
公共类枚举测试{
@试验
public void testBothMethods(){
最终的ComputerComponent c1=新的ComputerComponent(ComputerComponentCategory.CPU.getLabel(),12.21);
最终的ComputerComponent c2=新的ComputerComponent(ComputerComponentCategory.MEMORY.getLabel(),23.45);
最终列表=数组.asList(c1,c2);
assertEquals(带过滤器的平均价格(列表),带过滤器的平均价格(列表),0.01);
}
带筛选器的受保护静态双平均价格(最终列表){
return list.stream()
.filter(line->line.getCategory().contains(“CPU”)
||line.getCategory()包含(“GPU”)
||line.getCategory()包含(“监视器”)
||line.getCategory()包含(“键盘”)
||line.getCategory()包含(“鼠标”)
||line.getCategory()包含(“存储”)
||line.getCategory()包含(“内存”))
.mapToDouble(计算机组件::getPrice)
.average()
.orelsetrow(NoSuchElementException::new);
}
受保护的静态双平均价格WithInenum(最终列表){
return list.stream()
.filter(line->ComputerComponentCategory.getValue(line.getCategory())!=null)
.mapToDouble(计算机组件::getPrice)
.average()
.orelsetrow(NoSuchElementException::new);
}
}
编辑:解释你的错误:
EnumUtils.getEnumMap(ComputerComponentCategory.class).keySet())
返回枚举名称的映射(而不是其标签
),因此检查仅适用于CPU
,因为名称和标签相同
其他方法也一样
您需要使用getLabel()
而不是name()
或使用equalsIgnoreCase
而不是contains
谢谢您的解释。你知道为什么EnumUtils.isValidEnum()不起作用吗?是的,同样的解释也适用<枚举的code>name
基本上是常量的字符串表示形式,例如“MONITOR”。您的类别可能使用“Monitor”标签,这显然不同(大写)。您可以将标签转换为UpperCase
,但我强烈建议您只使用枚举提供的便捷方法,就像我的答案一样。也许更好:不要在ComputerComponent中使用category标签,只需将category属性键入为ComputerComponentCategory并直接使用枚举即可。
public class EnumTest {
@Test
public void testBothMethods() {
final ComputerComponent c1 = new ComputerComponent(ComputerComponentCategory.CPU.getLabel(), 12.21);
final ComputerComponent c2 = new ComputerComponent(ComputerComponentCategory.MEMORY.getLabel(), 23.45);
final List<ComputerComponent> list = Arrays.asList(c1, c2);
assertEquals(averagePriceWithFilter(list), averagePriceWithInEnum(list), 0.01);
}
protected static double averagePriceWithFilter(final List<ComputerComponent> list) {
return list.stream()
.filter(line -> line.getCategory().contains("CPU")
|| line.getCategory().contains("GPU")
|| line.getCategory().contains("Monitor")
|| line.getCategory().contains("Keyboard")
|| line.getCategory().contains("Mouse")
|| line.getCategory().contains("Storage")
|| line.getCategory().contains("Memory"))
.mapToDouble(ComputerComponent::getPrice)
.average()
.orElseThrow(NoSuchElementException::new);
}
protected static double averagePriceWithInEnum(final List<ComputerComponent> list) {
return list.stream()
.filter(line -> ComputerComponentCategory.getValue(line.getCategory()) != null)
.mapToDouble(ComputerComponent::getPrice)
.average()
.orElseThrow(NoSuchElementException::new);
}
}