如何比较 'list of string' 与 'enum string values' 与 return 的最大匹配?
How to compare 'list of string' with 'enum string values' to return maximum match?
当前代码发送 List<String>
但 returns 如果所有值都匹配则枚举
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]
}
}
但现在的要求是如果我们得到 List as 那么应该返回最大匹配枚举
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
注意:在 ST & RC 或任何冲突的情况下,我们需要选择第一个。 (像ST,RC我们可以挑MA_ON)
任何人都可以建议如何在 getValue 中实现相同的枚举吗? (代替 containsALL 如果我添加 contains 那么它不起作用。不确定它是否需要一些 maxmatch 等)
如果我正确理解你的问题,你只需要
- 知道有多少个常见字符串有
codes
和 values
(对于每个枚举)
- 过滤掉没有共同元素的元素
- 选择一个具有最多公共元素的元素(或者如果有很多元素,则从中选择第一个)
为了简化我们的工作,我们可以创建辅助方法来仅查找两个列表中的公共元素。它看起来像(我假设您的列表只有唯一元素)
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;
}
有了这个我们可以
- 将每个枚举映射到包含
enum, amountOfCommonElements
的对(我们可以使用 Map.entry
创建对),
- 过滤器对,其中
amountOfCommonElements
为 0,
- 选择最大值
amountOfCommonElements
- 仅从那对
enum
.
演示:
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
}
}
当前代码发送 List<String>
但 returns 如果所有值都匹配则枚举
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]
}
}
但现在的要求是如果我们得到 List as 那么应该返回最大匹配枚举
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
注意:在 ST & RC 或任何冲突的情况下,我们需要选择第一个。 (像ST,RC我们可以挑MA_ON)
任何人都可以建议如何在 getValue 中实现相同的枚举吗? (代替 containsALL 如果我添加 contains 那么它不起作用。不确定它是否需要一些 maxmatch 等)
如果我正确理解你的问题,你只需要
- 知道有多少个常见字符串有
codes
和values
(对于每个枚举) - 过滤掉没有共同元素的元素
- 选择一个具有最多公共元素的元素(或者如果有很多元素,则从中选择第一个)
为了简化我们的工作,我们可以创建辅助方法来仅查找两个列表中的公共元素。它看起来像(我假设您的列表只有唯一元素)
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;
}
有了这个我们可以
- 将每个枚举映射到包含
enum, amountOfCommonElements
的对(我们可以使用Map.entry
创建对), - 过滤器对,其中
amountOfCommonElements
为 0, - 选择最大值
amountOfCommonElements
- 仅从那对
enum
.
演示:
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
}
}