[英]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.