我正在尝试创建一个包含n个元素的对象列表。我希望以尽可能Java 8的方式来实现这一点。类似于在此处提出的C#问题: Creating N objects and adding them to a list
像这样:
List <Objects> getList(int numOfElements)
{
}
我正在尝试创建一个包含n个元素的对象列表。我希望以尽可能Java 8的方式来实现这一点。类似于在此处提出的C#问题: Creating N objects and adding them to a list
像这样:
List <Objects> getList(int numOfElements)
{
}
List <Object> getList(int numOfElements){
return IntStream.range(0, numOfElements)
.mapToObj(Object::new) // or x -> new Object(x).. or any other constructor
.collect(Collectors.toList());
}
Collections.nCopies(n, T)
Collections.nCopies(n, T)
将返回一个不可修改的List<T>
。如果您需要获取可编辑的 List<T>
,则应创建一个空列表,然后调用 addAll
,并将 nCopies
的结果传递给它。List temp = new ArrayList<>();
temp.addAll(Collections.nCopies(n, T));
return temp;
- afj88return new ArrayList<>(Collections.nCopies(n, T));
- Bonnev您可以使用Stream.generate(Supplier<T>)
与对构造函数的引用结合使用,然后使用Stream.limit(long)
指定要构造多少个:
Stream.generate(Objects::new).limit(numOfElements).collect(Collectors.toList());
对我来说,这比使用IntStream
进行迭代更易读,并且更清楚地说明了意图,例如Alberto Trindade Tavares建议的那样。
如果你想要在复杂度和内存使用方面表现更好,可以将结果大小传递给Stream.collect(Collector<? super T,A,R>)
:
Stream.generate(Objects::new).limit(numOfElements).collect(Collectors.toCollection(() -> new ArrayList<>(numOfElements)));
IntStream
方法 - 因为这仍然是一个无限流(使用limit方法不能引入SIZED
属性);除此之外还要点赞+1。 - EugeneArrays.asList(IntStream.range(0, numOfElements).mapToObj(Objects::new).toArray(Objects[]::new));
。 - HolgerArraySpliterator
比RangeIntSpliterator
更好吗? - EugenetoArray
将立即分配最终数组,并让每个线程写入该数组的正确部分,与collect(Collectors.toList())
对比,后者收集到本地列表并需要额外的合并步骤。此外,toList()
使用的列表可能需要进行(多次)容量增加操作。也可以参见此评论。 - HolgerStream.generate(() -> new SomeClassName(someValue_01, ... , someValue_N)) .limit(size) .collect(Collectors.toList());
或者我们甚至可以通过传递和自定义 supplier 来进行生成。 - kelgwiin使用Java 8中的streams
,等效于您提到的C#代码的实现如下(建议使用mapToObj,由@Eugene建议):
List <Objects> getList(int numOfElements)
{
return IntStream.range(0, numOfElements)
.mapToObj(x -> new Objects())
.collect(Collectors.toList());
}
x
,所以看起来应该是 .map(x -> new Objects(x))
或更好的 .map(Objects::new)
。 - Eugene如果您不介意使用第三方依赖,则可以使用Eclipse Collections实现以下功能:
List<Object> objects = Lists.mutable.withNValues(10, Object::new);
Verify.assertSize(10, objects);
List <Objects> getList(int numOfElements)
{
List<Objects> objectList = new LinkedList<>();
for(int i = 0; i <= numOfElements; i++)
{
objectList.add(new Object());
}
return objectList;
}
return IntStream.range(0, numOfElements)
.mapToObj(x -> new Objects())
.collect(Collectors.toList());
感谢@Alberto Trindade比我更快地发布了这篇文章。