The current code send List<String>
but returns Enum if all values matches
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
public enum Rara {
MA_ON("ST"),
MA_MAN("ST", "YS"),
MA_IP("ST", "YS", "IC"),
CODE("RC");
Rara(String... codes) {
this.codes = List.of(codes);
}
private List<String> codes;
public static Optional<Rara> getValue(List<String> values){
return Arrays.stream(values())
.filter(rara -> rara.codes.containsAll(values))
.findFirst();
}
}
public class Main {
public static void main(String args[]){
System.out.println(Rara.getValue(Arrays.asList("ST", "YS")));
// Optional[MA_MAN]
System.out.println(Rara.getValue(Arrays.asList("ST")));
// Optional[MA_ON]
}
}
But now requirements are if we get List as then max match enum should be returned
System.out.println(Rara.getValue(Arrays.asList("ST", "YS", "IC", "BLABLA")));
//Should return MA_IP
System.out.println(Rara.getValue(Arrays.asList("ST", "Bla", "Blabla", "BLABLA")));
//Should return MA_ON
Note: IN case of ST & RC or any conflicting We need to pick the first one. (Like ST, RC we can pick MA_ON)
can anyone suggest how to achieve in same enum in getValue? (In place of containsALL if i add contains then it doesn't work. Not sure if it requires some maxmatch etc)
CodePudding user response:
If I understood your problem correctly all you need is to know
- how many common strings has
codes
andvalues
(for each enum) - filter out those with no common elements
- pick one with maximum amount of common elements (or in case of many maxes first one from them)
To simplify our job we can create helper method to find only common elements in two lists. It can look like (I am assuming your Lists will have only unique elements)
private static List<String> commonElements(List<String> list1, List<String> list2) {
List<String> common = new ArrayList<>(list1); // to avoid modifying `list1`
common.retainAll(list2); // leaves in `common` only elements from `list2`
return common;
}
With this we can
- map each enum to pair containing
enum, amountOfCommonElements
(we can useMap.entry
to create pairs), - filter pairs where
amountOfCommonElements
is 0, - pick pair with max
amountOfCommonElements
- get from that pair only
enum
.
Demo:
enum Rara {
MA_ON("ST"),
MA_MAN("ST", "YS"),
MA_IP("ST", "YS", "IC"),
CODE("RC");
Rara(String... codes) {
this.codes = List.of(codes);
}
private List<String> codes;
private static List<String> commonElements(List<String> list1, List<String> list2) {
List<String> common = new ArrayList<>(list1); // to avoid modifying `list1`
common.retainAll(list2); // leaves in `common` only elements from `list2`
return common;
}
public static Optional<Rara> getValue(List<String> values){
return Arrays.stream(values())
.map(en -> Map.entry(en, commonElements(en.codes, values).size()))
.filter(entry -> entry.getValue()>0)
.max(Comparator.comparing(Map.Entry::getValue))
.map(Map.Entry::getKey);
}
}
class Main {
public static void main(String args[]){
System.out.println(Rara.getValue(Arrays.asList("ST", "YS")));
// Optional[MA_MAN]
System.out.println(Rara.getValue(Arrays.asList("ST")));
// Optional[MA_ON]
System.out.println(Rara.getValue(Arrays.asList("ST", "RC")));
// Optional[MA_ON]
System.out.println(Rara.getValue(Arrays.asList("STB", "RCC")));
//Optional.empty
}
}