【发布时间】:2010-10-14 02:07:44
【问题描述】:
我有一个
List<Cat>
按猫的生日排序。有没有一种有效的 Java 集合方法来查找 1983 年 1 月 24 日出生的所有猫?或者,一般来说什么是好的方法?
【问题讨论】:
-
我本来打算提交一个答案,但由于 binarySearch 不能保证返回第一个结果,所以那个答案就没有了。
标签: java list collections findall sorted
我有一个
List<Cat>
按猫的生日排序。有没有一种有效的 Java 集合方法来查找 1983 年 1 月 24 日出生的所有猫?或者,一般来说什么是好的方法?
【问题讨论】:
标签: java list collections findall sorted
假设猫按生日排序,这将给出其中一只生日正确的猫的索引。从那里,您可以前后迭代,直到找到一个不同生日的人。
如果列表很长和/或同一天生日的猫不多,这应该是直接迭代的重大胜利。
这是我正在考虑的那种代码。请注意,我假设一个random-access 列表;对于链表,你几乎被迭代困住了。 (感谢 fred-o 在 cmets 中指出这一点。)
List<Cat> cats = ...; // sorted by birthday
List<Cat> catsWithSameBirthday = new ArrayList<Cat>();
Cat key = new Cat();
key.setBirthday(...);
final int index = Collections.binarySearch(cats, key);
if (index < 0)
return catsWithSameBirthday;
catsWithSameBirthday.add(cats.get(index));
// go backwards
for (int i = index-1; i > 0; i--) {
if (cats.get(tmpIndex).getBirthday().equals(key.getBirthday()))
catsWithSameBirthday.add(cats.get(tmpIndex));
else
break;
}
// go forwards
for (int i = index+1; i < cats.size(); i++) {
if (cats.get(tmpIndex).getBirthday().equals(key.getBirthday()))
catsWithSameBirthday.add(cats.get(tmpIndex));
else
break;
}
return catsWithSameBirthday;
【讨论】:
二分搜索是经典的方法。
澄清:我说你使用二进制搜索。没有一个具体的方法。算法是:
//pseudocode:
index = binarySearchToFindTheIndex(date);
if (index < 0)
// not found
start = index;
for (; start >= 0 && cats[start].date == date; --start);
end = index;
for (; end < cats.length && cats[end].date == date; ++end);
return cats[ start .. end ];
【讨论】:
Collections.binarySearch 方法。二分查找查找单个元素的索引。所有其他具有相同生日的元素都在找到的元素旁边。您可以通过一个循环获得所有这些。很经典。
Google Collections 可以通过使用谓词并创建谓词匹配日期的过滤集合来做你想做的事。
【讨论】:
如果您需要快速搜索,请使用以生日为关键字的 HashMap。如果您需要对键进行排序,请使用 TreeMap。
因为你想让多只猫有相同的生日,你需要在 Hast/TreeMap 中使用一个 Collection 作为一个值,例如
Map<Date,Collection<Cat>>
【讨论】:
除非您以某种方式按日期索引集合,否则唯一的方法是遍历所有集合
【讨论】: