【问题标题】:How to code a class that has to implement Comparator and has to compare by multiple values, using Java8? [duplicate]如何使用 Java8 编写一个必须实现 Comparator 并且必须通过多个值进行比较的类? [复制]
【发布时间】:2016-05-29 15:08:45
【问题描述】:

首先,我对 Java 8 很陌生,也许我的问题根本不适用于它...
所以,我有一个类,它有一个包 private int 和一个 String 字段。我必须按分数然后按名称比较实例。解决方案是一个必须实现 Comparator 的类,我想在 Java 8 中解决它,因为我会编写这样的代码,而不需要所需的类:

Arrays.sort(players, Comparator.comparing(Player.score).thenComparing(Player.name);

(玩家是玩家的数组)
有可能吗?重写的比较方法应该返回一个int,我什至无法获得编译代码:( 我首先尝试了这个:

public class Sorter implements Comparator<Player> {
    @Override
    public int compare(Player o1, Player o2) {
        return (int)(p1, p2) -> Comparator.comparing(Player.score).thenComparing(Player.name);
    }
}

它在 Player.score 和 Player.name 处失败,因为“不能从静态上下文引用非静态参考分数”我不明白这怎么会是静态上下文。
然后我临时为 score 和 name 创建了 getter 方法(它必须保持没有 getter),问题变成了“int 不是函数式接口”。
如果有人能说出这是否可能,我将不胜感激,如果可以,请引导我找到正确的解决方案。
非常感谢!

编辑:我的问题不是如何使用静态变量问题的重复,因为我想知道我的任务是否可以在 Java 8 中解决如果是,如何。在我的班级中有一个比较器作为一个字段,似乎可以解决这个问题(如果可以访问 getter)。

【问题讨论】:

  • 您需要将Functions 提供给comparingthenComparing。试试Comparator.comparing(player-&gt;player.score).thenComparing(player-&gt;player.name)
  • compare 应该返回 int 而不是 Comparator。如果 SorterComparator 与 lambda 表达式作为静态最终字段,则您的 compare 函数可以调用其 compare 函数。
  • 谢谢@HankD!如果我暂时为字段添加吸气剂,那效果很好。由于我无法更改给定的情况,public class Sorter implements Comparator&lt;Player&gt; { private static final Comparator&lt;Player&gt; comp = Comparator.comparing(Player.score).thenComparing(Player.name); @Override public int compare(Player o1, Player o2) { return comp.compare(o1, o2); } } 仍然存在非静态字段的问题.. 无法引用...等等。我在 .comparing: p -> ((Player)p) 中尝试了类似的操作。得分了,但还是没有结果……你有更多的想法吗?
  • 你能创建与 Player 包名相同的新类吗?同一包中的其他类对包私有成员具有可见性。可以编辑播放器吗?你能创建一个添加访问器的子类吗?
  • 对每个问题都没有 :( 似乎具有这些限制的任务是针对良好的旧 Java 而不是 lambdas。无论如何,您在 Sorter 类中提供了带有 Comparator 字段的解决方案(工作得很好,因为 getter 是那里),所以谢谢你!

标签: arrays sorting java-8 comparator


【解决方案1】:

这里有几个问题:

  1. 您确实应该使用 getter 而不是引用 Player 对象中的公共字段。 (我在我的例子中改变了)
  2. Person::getScore 是一个方法引用,稍后会调用 get score 方法。
  3. 您不需要比较器实现类。我们的想法是使用 lambdas 来代替对它的需求。

以下工作示例显示了要做什么:

import java.util.*;

public class PlayTest {

    static class Player {
        private int score;
        private String name;
        public int getScore() {
            return score;
        }
        public void setScore(int score) {
            this.score = score;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public String toString() {
            return name;
        }
    }


    public static void main(String[] args) {
        Player p1 = new Player();
        p1.setScore(100);
        p1.setName("test 2");
        Player p2 = new Player();
        p2.setScore(100);
        p2.setName("test 1");

        List<Player> list= new ArrayList<>();
        list.add(p1);
        list.add(p2);

        Comparator<Player> comparator = Comparator.comparing(Player::getScore).thenComparing(Player::getName);

        Collections.sort(list, comparator);

        System.out.println(list);
    }
}

【讨论】:

  • 感谢您这样做,但不幸的是,我写的条件已经给出,(字段没有 getter,使用 Arrays.sort(),实现 Comparator 的新类),我无法更改它们。否则我会像你那样解决问题;)
  • 啊。所以这是家庭作业。如果你需要一个实现 Comparator 的新类,我认为作业的目的是你不使用 lambdas。
  • 不,这是一个挑战。是的,你可能是对的,我只是想知道用 lambdas 解决它是否有意义,这就是我寻求想法的原因。 @Hank D 几乎有答案:)
猜你喜欢
  • 2011-12-22
  • 1970-01-01
  • 1970-01-01
  • 2018-12-10
  • 1970-01-01
  • 2017-04-19
  • 2019-02-23
  • 2020-02-20
  • 1970-01-01
相关资源
最近更新 更多