0

我正在开发一些元素的历史视图。每个元素都有一个开始和结束日期。期间可能不重叠,因此每个开始日期必须等于或晚于其前任的结束日期。如果结束日期为空,则元素从其开始日期一直处于活动状态,直到已知结束日期为止。

出于测试目的,我创建了这个类:

public class Entry implements Comparable<Entry>
{
    Integer start;
    Integer end;

    public Entry(Integer s, Integer e)
    {
        start = s;
        end = e;
    }

    @Override
    public boolean equals(Object obj)
    {
        if (obj instanceof Entry)
        {
            return compareTo((Entry) obj) == 0;
        }
        return false;
    }

    @Override
    public int compareTo(Entry o)
    {
        if (o.end != null // other ends before or when this starts
                && (o.end.equals(start) || o.end < start ))
        {
            return 1;
        }
        if (end != null // other starts after or when this ends
                && (o.start.equals(end) || o.start > end ))
        {
            return -1;
        }
        return 0;
    }
}

我使用 TreeSet 对元素进行排序。现在我遇到的问题是我无法获得当前活动或第一个到来的元素。

查看 JavaDoc 天花板方法应该可以解决问题:

返回此集合中大于或等于给定元素的最小元素,如果没有这样的元素,则返回 null。

但是,这不起作用。

在一个测试用例中,我创建了一个带有一堆条目的 TreeSet:

TreeSet<Entry> ts = new TreeSet<Entry>();
ts.add(new Entry(1, 3));
ts.add(new Entry(3, 5));
ts.add(new Entry(5, 7));
ts.add(new Entry(7, 9));
ts.add(new Entry(9, 11));
ts.add(new Entry(11, 13));
ts.add(new Entry(13, 15));

然后我使用以下代码获得天花板:

ts.ceiling(new Entry(5, null));

我期望的结果是开始 5 和结束 7 的条目(“相等”条目)。然而,结果是开始 7 和结束 9 的条目(更大的条目)。两个结果都等于或大于给定元素。但由于 JavaDoc 提到它返回最少的元素,我希望 5-7 条目。

4

1 回答 1

2

您正在定义什么是最少的元素(通过定义compareTo)。

你自己在说:

“两个结果相等”

因此,当 API 引用最小元素时,它指的是有序集合中的参数之后或等于(ceil)的元素。现在打印您的订购集:

[(1, 3), (3, 5), (5, 7), (7, 9), (9, 11), (11, 13), (13, 15)]

因此,上限首先查找等于5, null(意味着compareTo返回 0)的元素,如果找到,则返回该元素。您有两个相等的元素(因此无需再寻找一个)。

就是天花板方法文档所指的,集合中的顺序(不是通过设置某种新的比较)。

公共E天花板(E e)

返回此集合中大于或等于给定元素的最小元素

请参阅TreeSet#ceiling(E e) API

所以它找到一个5, 7or 7,9(两者都等于5, null)并返回它首先找到的那个,这是7,9根据实现的。

TreeSet 实际上是幕后的树结构(doh),它在该树中的哪个节点命中两个相等的节点取决于实现的细节和可能的插入顺序。

您的 compareTo/equals 不遵守正常/推荐的规则(对于尝试使用它们的 Tree 肯定是不利的)。如果 A 和 B 相等且 C 和 B 相等,则 A 和 C 应该相等,而compareTo 函数不是这种情况。

于 2012-05-23T20:06:29.613 回答