如何比较 '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 等)

如果我正确理解你的问题,你只需要

  • 知道有多少个常见字符串有 codesvalues(对于每个枚举)
  • 过滤掉没有共同元素的元素
  • 选择一个具有最多公共元素的元素(或者如果有很多元素,则从中选择第一个)

为了简化我们的工作,我们可以创建辅助方法来仅查找两个列表中的公共元素。它看起来像(我假设您的列表只有唯一元素)

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
    }
}