【问题标题】:create custom comparator in case of closure over variable在关闭变量的情况下创建自定义比较器
【发布时间】:2017-10-30 09:32:49
【问题描述】:
private Optional<Example> getTopExample(List<Example> exampleList, String input) {
String lowerCaseInput = input.toLowerCase();
Comparator<Example> exampleNearestMatchComparator = exampleComparator
                    .thenComparing((Example ex1, Example ex2) -> {
                        String name1LowerCase = getNameOfExample(ex1).toLowerCase();
                        String name2LowerCase = getNameOfExample(ex2).toLowerCase();
                        if (name1LowerCase.startsWith(input) && name2LowerCase.startsWith(lowerCaseInput)) {
                            return name1LowerCase.length() <= name2LowerCase.length() ? 1 : -1;
                        } else if (name1LowerCase.startsWith(lowerCaseInput)) {
                            return 1;
                        } else if (name2LowerCase.startsWith(lowerCaseInput)) {
                            return -1;
                        } else {
                            if (name1LowerCase.contains(lowerCaseInput) && name2LowerCase.contains(lowerCaseInput)) {
                                return name1LowerCase.length() <= name2LowerCase.length() ? 1 : -1;
                            } else if (name1LowerCase.contains(lowerCaseInput)) {
                                return 1;
                            } else if (name2LowerCase.contains(lowerCaseInput)) {
                                return -1;
                            } else {
                                return 1;
                            }
                        }
                    });
            return exampleList.stream())
                    .max(exampleNearestMatchComparator);
          }

我有一个 Example 类型的自定义对象,它具有名称、分数等属性...我想定义一个方法,其目的是从示例列表中检索最重要的示例。

“分数”最高的示例是顶部(最重要)示例,我已经有一个名为“exampleComparator”的比较器来实现此目的。在某些情况下, 有可能两个示例具有相同的分数。在这种情况下,我想选择名称几乎接近“输入”的示例。正如您在代码中看到的那样,我创建了一个“exampleNearestMatchComparator”。

如您所见,每次调用“getTopExample”时都会创建一个新的“exampleNearestMatchComparator”。我想在此方法之外定义“exampleNearestMatchComparator”,但您可以看到“exampleNearestMatchComparator” 取决于动态“输入”(每次调用 getTopExample 时都会发生变化)。 据我了解,流中的 lambda 是“封闭值而不是变量”(http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html),我无法在此方法之外定义“exampleNearestMatchComparator”。

我说的对吗?欢迎提出任何建议。

【问题讨论】:

    标签: lambda java-stream comparator


    【解决方案1】:

    如果您想防止每次都重新创建最近的匹配比较器,您可以在使用比较器之前更新 inputlowerCaseInputcomparator 字段:

    private Comparator<Example> exampleComparator             = // your comparator;
    private String              input;
    private String              lowerCaseInput;
    private Comparator<Example> nearestMatchComparator        = // your lambda;
    private Comparator<Example> exampleNearestMatchComparator = exampleComparator.thenComparing(nearestMatchComparator);
    
    private Optional<Example> getTopExample(List<Example> exampleList, String input)
    {
        this.input = input;
        this.lowerCaseInput = input.toLowerCase();
        return exampleList.stream().max(exampleNearestMatchComparator);
    }
    

    不过,将 lambda 封装到一个单独的类中可能会更好,该类具有 input 的设置器。

    private Comparator<Example> exampleComparator             = // your comparator;
    private Comparator<Example> nearestMatchComparator        = new NearestMatchComparator();
    private Comparator<Example> exampleNearestMatchComparator = exampleComparator.thenComparing(nearestMatchComparator);
    
    private Optional<Example> getTopExample(List<Example> exampleList, String input)
    {
        nearestMatchComparator.setInput(input);
        return exampleList.stream().max(exampleNearestMatchComparator);
    }
    
    private final class NearestMatchComparator
        implements Comparator<Example>
    {
        private String input;
        private String lowerCaseInput;
    
        public void setLowerCaseInput(String input)
        {
            this.input = input;
            this.lowerCaseInput = input.toLowerCase();
        }
    
        @Override
        public int compare(Example ex1, Example ex2)
        {
            // your implementation
        }
    }
    

    【讨论】:

    • 感谢您的建议。让我检查一下其他选择。
    猜你喜欢
    • 2022-11-15
    • 1970-01-01
    • 2020-03-08
    • 1970-01-01
    • 2017-07-09
    • 2021-05-17
    • 1970-01-01
    • 2011-02-14
    • 1970-01-01
    相关资源
    最近更新 更多