加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 使用自定义Comparator的最大流

发布时间:2020-12-15 05:17:57 所属栏目:Java 来源:网络整理
导读:下面是我专门编写的代码,用于在 Java 8 Stream中使用带有max的自定义Comparator. import java.math.BigDecimal;import java.util.*;public class BigDecimalMax { public static BigDecimal getBigDecimalMax(ListforTest list) { return list.stream() .fil
下面是我专门编写的代码,用于在 Java 8 Stream中使用带有max的自定义Comparator.

import java.math.BigDecimal;
import java.util.*;

public class BigDecimalMax  {

    public static BigDecimal getBigDecimalMax(List<forTest> list) {

        return list.stream()
            .filter(t -> t.id % 2 == 0)
            .max(forTestComparator::compare)  //<-- syntax error ----------
            .orElse(null);
    }

    public static class forTestComparator implements Comparator<forTest> {

        @Override
        public int compare(forTest val1,forTest val2) {
            return val1.value.compareTo(val2.value);
        }
    }

    public static void main(String[] args) {

        List<forTest> lst = new ArrayList<>();
        Random rn = new Random();
        BigDecimalMax bdm = new BigDecimalMax();

        for (int i=1; i<22; ++i) {
            lst.add(bdm.new forTest(i,BigDecimal.valueOf(rn.nextLong())));
        }

        System.out.println(getBigDecimalMax(lst));

    }

    class forTest {
        public int id;
        public BigDecimal value;

        forTest(int id,BigDecimal value) {
            this.id = id;
            this.value = value;
        }

        @Override
        public String toString() {
            return "forTest{" +
                    "id=" + id +
                    ",value=" + value +
                    '}';
        }
    }
}

我在方法参考上遇到语法错误,我不明白.

Error:(15,18) java: incompatible types: invalid method reference
    cannot find symbol
      symbol:   method compare(BigDecimalMax.forTest,BigDecimalMax.forTest)
      location: class BigDecimalMax.forTestComparator

而IntelliJ IDEA抱怨无法从静态上下文引用非静态方法.

我到底错在了什么?

附加说明(2014年4月24日):

>我现在理解语法错误的原因.谢谢.
>这里真的需要定制比较器吗?

由于BigDecimal实现Comparable但似乎没有实现Comparator(它有CompareTo()但没有Compare())我认为自定义Comparator是必要的.这就是为什么我不能只使用Comparator.comparing(ft – > ft.value).我的逻辑中有缺陷吗?

解决方法

Sotirios Delimanolis’ answer显示了如何解决问题,但我还有一些事情需要补充.

如果您已经有一个实现Comparator的类,则不需要对其compare()方法使用方法引用.您可以直接传递它的实例,因为max()接受对比较器的引用:

.max(new forTestComparator())

要么

forTestComparator instance = new forTestComparator();
    ...
    .max(instance)

但是,Comparator上的组合函数通常不需要有一个实现Comparator的类.例如,你可以完全摆脱forTestComparator类,只需这样做:

.max(Comparator.comparing(ft -> ft.value))

或者如果forTest有明显的getValue()方法,可以重写stream max()调用,如下所示:

.max(Comparator.comparing(forTest::getValue))

另外,如果你想让forTest实现Comparable接口,你可以这样做:

public class forTest implements Comparable<forTest> {
    @Override
    public int compareTo(forTest other) {
        return this.value.compareTo(other.value);
    }
    ...
}

以及在Comparable上使用max()的方法是:

.max(Comparator.naturalOrder())

两种风格的笔记:

>我强烈反对在Optional的实例上使用orElse(null).这是允许的,尽管它的主要目的可能是将新的Java 8 API改进为期望为空以表示缺少值的代码.如果可能,请避免使用orElse(null),因为这会强制调用者检查null.相反,用实际值替换替换缺席值,或者将Optional本身返回给调用者,这样调用者就可以应用它想要的任何策略.>我建议坚持大写的混合大小写类名称的既定Java命名约定. forTest和forTestComparator的类名使得这些代码难以使用,因为它们看起来不像类名.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读