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);
}
I have an enum as
public enum ComputerComponentCategory {
CPU("CPU"),
MONITOR("Monitor"),
KEYBOARD("Keyboard"),
MOUSE("Mouse"),
GPU("GPU"),
MEMORY("Memory"),
STORAGE("Storage"),
NULL("NOT DEFINED");
private String label;
ComputerComponentCategory(String label) {
this.label = label;
}
public String getLabel() {
return this.label;
}
public static ComputerComponentCategory getValue(String label) {
switch(label) {
case "CPU":
return CPU;
case "Monitor":
return MONITOR;
case "Keyboard":
return KEYBOARD;
case "Mouse":
return MOUSE;
case "GPU":
return GPU;
case "Memory":
return MEMORY;
case "Storage":
return STORAGE;
default:
return NULL ;
}
}
}
I pass a list of ComputerComponent class to the averagePrice() function which has two fields of price which is of type double and category which is of type String.
My list has 4 elements with categories as "CPU", "Mouse", "Keyboard" and "Storage" with their respective prices as 34.0, 155.0, 23.0 and 75.0.
When I try to use inEnum(), isInEnum() or EnumUtils.isValidEnum() functions, I get the average price as 34.0 which I think that they just return the price of the first element rather than the average.
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"))
I get the correct average value of 71.75.
The implementations that I have used for isInEnum() and inEnum() functions are the following:
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 ;
}
How can I use enums correctly with java streams to filter by valid category names and get the correct average value of price?
What mistake I am making when using streams and its functions ?