【问题标题】:Moving Java Comparator logic out of entity?将Java比较器逻辑移出实体?
【发布时间】:2016-05-31 13:56:59
【问题描述】:

我目前有一个javaEntitiesCatKitten

下面是包含当前 comparator 逻辑的 Cat 实体,用于对 Cat 拥有最老小猫的 Cat 实体进行排序

public class Cat implements Comparable<Cat>
{

    //other fields and methods

    @OneToMany(mappedBy = "cat",fetch = FetchType.EAGER)
    private List<Kitten> kittenList= new ArrayList<Kitten>();

     public DateTime getOldestBornValueForKittenInList(){

        return kittenList.stream().min(Comparator.comparing(Kitten::getBorn))
                .get().getBorn();
    }

    public int compareTo(Cat c) {

        //fist compare on the oldest Created DateTime Value
        int i = getOldestBornValueForKittenInList().compareTo(c.getOldestBornValueForKittenInList());
        if (i != 0){
            return i;
        }

    }

}

不再希望我的 Cat 实体实现 comparable 接口。我可以在我的应用程序中调用比较器吗?

即如果我想要 ordered Map 的猫和它们的小猫列表,其中最老的小猫是地图中的第一个条目:

Map<Cat, List<Kitten>> mapOfCatsAndKittens = new HashMap<Cat, List<Kitten>>();

【问题讨论】:

  • 一般来说,在实体类中包含逻辑是不好的做法,使用自动装配实体的服务来应用您的逻辑
  • 为什么不TreeMap?它被设计为采用comparator
  • @RoelStrolenberg 你能举例说明我可以用它来替换实体逻辑的服务吗?
  • @Tirath 谢谢,请举例说明如何将比较器添加到树形图中?
  • 我从未说过添加。无论如何,您可以在这里查看 TreeMap -docs.oracle.com/javase/7/docs/api/java/util/TreeMap.html。查看构造函数。你可以传入你的 comparator 实现。

标签: java dictionary java-stream comparator


【解决方案1】:

请注意,您的代码包含几个不必要的重复项。在

public DateTime getOldestBornValueForKittenInList() {
    return kittenList.stream().min(Comparator.comparing(Kitten::getBorn)).get().getBorn();
}

您让比较器获取属性getBorn,尽管这是您唯一感兴趣的属性。因此您可以将操作简化为

public DateTime getOldestBornValueForKittenInList() {
    return kittenList.stream().map(Kitten::getBorn).min(Comparator.naturalOrder()).get();
}

通过首先映射到属性,您可以获得DateTime 元素流,您可以自然地比较这些元素,而无需在每次比较时重新获取属性。结果已经是最小值DateTime

请记住,无论哪种情况,如果列表为空,操作都会失败。

但是Comparator.comparing 工厂仍然占有一席之地。当您想通过属性比较 Cat 对象时:

Comparator<Cat> oldestKitten=Comparator.comparing(Cat::getOldestBornValueForKittenInList);

您可以使用这样的比较器来创建按该属性排序的地图

Map<Cat, List<Kitten>> mapOfCatsAndKittens = new TreeMap<>(oldestKitten);

或对Cats 的列表进行排序:

List<Cat> list= … ; // should be a mutable list implementation, e.g. ArrayList
// perhaps add (some more) Cats
list.sort(oldestKitten);

【讨论】:

  • 谢谢,我也可以在比较器中使用多个子句吗?即,如果我想先检查小猫的 oldBornValue,然后再检查另一个子句?如果前两个相等?
  • Comparator.comparing(Cat::firstProperty).thenComparing(Cat::nextProperty)
  • 谢谢,所以这个 Treemap 中的第一个键将首先是拥有最老小猫的猫,第二个键将是拥有第二大小猫的猫,依此类推?
  • 如果猫 #1 拥有最老的小猫和第二大的小猫,则地图中的第二个值将是拥有第三大小猫的猫。可以吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-16
  • 2010-12-24
相关资源
最近更新 更多