Java:将项目“归纳”到列表中

2022-09-03 14:29:25

我有一个具有方法(返回不可变列表)的方法,对于我拥有的每个项目,我需要创建一个项目的列表,后跟其子项。ItemList<Item> getChildren()

缺点”(在Lisp/Scheme意义上)我的项目以创建新的不可变列表的最快方法是什么?我当然可以做以下事情,但它似乎是错误的/浪费的:

public List<Item> getItemAndItsChildren(Item item)
{
    if (item.getChildren.isEmpty())
        return Collections.singletonList(item);
    else
    {
        // would rather just "return cons(item, item.getChildren())"
        // than do the following -- which, although straightforward,
        // seems wrong/wasteful.
        List<Item> items = new ArrayList<Item>();
        items.add(item);
        items.addAll(item.getChildren());
        return Collections.unmodifiableList(items);
    }
}

答案 1

我会改变我的要求。在大多数情况下,您不需要在界面中使用a,a会做得很好。方法是:ListIterable

public Iterable<Item> getItemWithChildren(Item item)    {
    return Iterables.unmodifiableIterable(
        Iterables.concat(
            Collections.singleton(item),
            item.getChildren()
        )
    );
}

这是缩短的版本(使用静态导入):

return unmodifiableIterable(concat(singleton(item), item.getChildren()));

答案 2

通过将 head 元素连接到可能在其他列表之间共享的尾部来创建新的不可变列表,这需要一个单链列表实现。Java没有开箱即用地提供类似的东西,所以你的解决方案和任何东西一样好。ArrayList

假设这些列表是短暂的,并且列表中没有成千上万的元素,它也将相对有效。如果您这样做,并且此操作占用了很大一部分执行时间,那么实施您自己的单链表可能是值得的。

我为提高现有效率所做的一项更改:使用容量(1 + 旧列表的大小)构建新列表。