列出实现是多个子列表的视图?

时间:2011-07-11 10:44:23

标签: java

我正在研究一个经常需要返回单个列表的软件,该列表包含许多其他列表的第一个(最多)N个元素。返回不会被客户修改 - 它是只读的。

目前,我正在做一些事情(为了便于阅读而简化的代码):

List ret = new ArrayList<String>();
for (List aList : lists) {
    // add the first N elements, if they exist
    ret.addAll(aList.subList(0, Math.min(aList.size(), MAXMATCHESPERLIST)));
    if (ret.size() >= MAXMATCHESTOTAL) {
        break;
    }
}
return ret;

我想避免创建新列表和使用addAll(),因为我不需要返回一个新列表,而且我每秒处理数千个元素。这种方法是我申请的主要瓶颈。

我正在寻找的是List的一个实现,它只包含每个包含列表的subList()结果(那些是廉价的视图,而不是实际的副本)。

我已经查看了通常的嫌疑人,包括java.util,Commons Collections,Commons Lang等,但不能为我的生活找到任何这样的实现。我很确定它必须在某个时候实施,希望我错过了一些明显的东西。

所以我转向你,Stack Overflow--是否有人意识到这样的实现?我可以自己写一个,但如果轮子在那里,我讨厌重新发明轮子。

非常欢迎有关替代更有效方法的建议!

可选的背景细节(可能与我的问题无关,但以防它可以帮助您理解我正在尝试做的事情):这是一个程序来填充填字游戏风格带有围绕主题的单词的网格。每个主题可以具有任意数量的候选词列表,按主题相关性的降序排列。例如,“电影”主题可以从电影标题列表开始,然后是演员列表,然后是可能与电影相关或可能不与电影相关的地方的通用列表,然后是英语单词的通用列表。每个列表都存储在通配符trie结构中,以允许快速查找满足网格约束(例如,“CAT”将存储在针对“CAT”,“CA?”,“C ??”键的trie'd列表中, “?AT”,......“???”等。列表从几个单词到几万个单词不等。

对于任何给定的查询,例如“C ??”,我想返回一个包含最多N个(比如50个)匹配单词的列表,按照与源列表相同的顺序排序。因此,如果列表1包含3个匹配“C ??”,列表2包含7,列表3包含100,我需要一个返回列表,首先包含列表1中的3个匹配,然后是列表2中的7个匹配,然后是40个我希望返回的“联合列表视图”操作比必须以与subList()的实现类似的方式连续调用addAll()更有效。

由于内存限制,缓存返回的列表不是一个选项 - 我的trie已经消耗了绝大多数(32位)最大大小的堆。

PS这不是作业,而是一个真实的项目。任何帮助非常感谢!

4 个答案:

答案 0 :(得分:1)

  1. 多次使用list.addAll()。简单,不需要外部罐子也无效。
  2. Jakarta集合框架有这样的列表。它是有效的,但需要外部罐子,不支持泛型。
  3. 从Google查看Guava。我认为它有你想要的东西。

答案 1 :(得分:1)

返回子列表有什么问题?这是 最快的方式,因为子列表不是副本,而是使用对支持数组的引用,而客户端是只读的 - 对我来说似乎很完美。

编辑:
我理解你为什么要将几个列表的内容组合起来制作更大的块,但是你可以改变你的客户端而不需要这么大的块吗?请参阅我的其他答案:BlockingQueue和生产者/消费者方法。

答案 2 :(得分:1)

您是否需要随机访问结果列表?或者您的客户端代码只迭代结果?

如果您只需要迭代结果。创建一个自定义列表实现,其中包含原始列表的列表:)作为实例字段。返回自定义迭代器,它将逐个从每个列表中获取项目,并在任何基础列表中没有更多项目时停止,或者您已经返回MAXMATCHESTOTAL项目。

通过一些想法,你可以做同样的随机访问。

答案 3 :(得分:0)

您是否考虑过使用BlockingQueue并让消费者在需要时逐个从队列中提取项目,而不是以块(列表)的形式获取项目?看来你正试图在这里重塑生产者/消费者模式。