繁体   English   中英

将元素和集合连接到新集合中

[英]Concatenating elements and Collections into a new Collection

我有一个Collection的元素和一个元素。 我希望我的getter函数看起来像这样

public List<Element> getElements(boolean includeOtherElement){

    if (includeOtherElement){
        return elements + otherElement; //Obviously this doesn't work, but I'm looking for something that would work like this
    }

    return elements;

}

有没有一种方法可以单行实现此行为,例如使用Stream API或类似的方法?

编辑:

从那以后,我意识到我不应该使用getter方法修改状态。

通常,您不希望getter函数更改变量。 我建议做类似temp = elements以返回temp变量,并通过temp.add(otherElement)添加额外的元素。 这样,您将不会更改当前变量,而仍会引起相同的行为。

如果您不想将otherElement添加到元素列表,但仍想返回列表,则必须提供一个新列表。

简单方法:

public List<Element> getElements(boolean includeOtherElement){

    if (includeOtherElement){
        List<Element> extendedList = new ArrayList<>(elements);
        extendedList.add(otherElement);
        return extendedList;
    }

    return elements;
}

这将创建列表的浅表副本。

如果确实需要,可以提供自己的列表实现,该实现将第一个索引委托给元素列表,将最后一个索引委托给otherElement;

我不确定该答案是否会完全适合您,但我认为这是API可能实现的一个很好的例子。 它在特定情况下可能会或可能不会使用的原因是,它取决于列表中恒定的额外元素的位置。

假设情况是您不想创建列表的副本,因为您实际上希望任何调用getter的人都能够修改列表。 或者,假设您只是不想复制该列表,可能是因为该列表非常大。 在这些情况下,您不想从列表中添加或删除多余的元素,而是要返回包含或排除多余元素的列表视图

使用List.subList(int, int)方法,使用现有API实际上可以做到这一点。 subList不会像String.substring(...)这样创建副本。 相反,返回的子列表是可变的(如果原始列表是可变的),并且对子列表的更改将一直显示到原始列表。

(尽管我应该注意,如果后备列表在结构上进行了修改,则子列表的语义将变得不确定,即,在保留对子列表的引用的同时,您不应在原始列表中添加/删除原始列表。如果通过以下方式更改原始列表,子列表以外的其他参考,则必须创建一个新的子列表。)

因此,您可以做的是保留包含所有元素的完整列表,然后返回该范围的子列表,其中不包括您不想返回的元素。

如果调用getter的代码不应该能够改变列表,则也可以将其与Collections.unmodifiableList(List)结合使用。

这是一个示例,显示了此操作:

import java.util.*;

class Example {
    public static void main (String[] args) {
        Example e = new Example();
        List<Object> sub = e.getList(false);
        // sublist is [1, 2, 3]
        System.out.printf("sublist is %s%n", sub);
        sub.add(0, -1);
        sub.add(1,  0);
        sub.add(5);
        // sublist is [-1, 0, 1, 2, 3, 5]
        System.out.printf("sublist is %s%n", sub);
        List<Object> all = e.getList(true);
        // full list is [element0, -1, 0, 1, 2, 3, 5]
        System.out.printf("full list is %s%n", all);
        // As a side-note, this sequence of calls is
        // e.g. what you aren't supposed to do:
        // all.add(something); // <- structural modification
        // sub.add(another);   // <- this is undefined
        // You have to make a new sublist first:
        // sub = e.getList(false);
        // sub.add(another);   // <- this is fine now
    }

    List<Object> objects = new ArrayList<Object>();
    Example() {
        objects.add("element0");
        objects.add(1);
        objects.add(2);
        objects.add(3);
    }

    List<Object> getList(boolean includeElement0) {
        if (includeElement0) {
            return objects;
        } else {
            return objects.subList(1, objects.size());
        }
    }
}

这是有关Ideone的示例: http ://ideone.com/PloZCh。


另外,虽然不返回List ,但是可以通过返回Stream来完成:

Stream<E> stream = list.stream();
if (includeOtherElement) {
    return Stream.concat(stream, Stream.of(otherElement));
} else {
    return stream;
}

我想这可能是在Java 8中执行此类操作的规范方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM