如果我想将一个列表添加到另一个列表中,我调用< code > target . adall(source)。
但是,如果我需要首先处理列表中的每个值怎么办?
我可以这样做
for(String s: source) {
target.add(s.toLowerCase());
}
或者使用java 8:
source.stream().map(x->x.toLowerCase()).forEachOrdered(target::add);
但无论哪种方式,我似乎都失去了<code>addAll<code>的性能优势。最有效的方法是什么?
您可以使用 Eclipse 集合中的收集()
模式,收集()
等效于来自 JDK 的 map()
。
MutableList<String> source = Lists.mutable.with("A", "B", "C");
MutableList<String> target = source.collect(String::toLowerCase);
如果您有现有的目标列表,则可以使用接受目标集合的 collect()
变体:
MutableList<String> source = Lists.mutable.with("A", "B", "C");
source.collect(String::toLowerCase, target);
如果您无法从< code>List更改列表:
List<String> source = Arrays.asList("A", "B", "C");
List<String> target = ListAdapter.adapt(source).collect(String::toLowerCase);
您还可以在List
上使用replace eAll()
:
List<String> source = Arrays.asList("A", "B", "C");
List<String> target = new ArrayList<>(source);
target.replaceAll(String::toLowerCase);
上面的解决方案可能性能更好,也可能性能更差,但是,它们都预先确定了目标列表的大小。
那么,什么是“添加全部
的性能优势”?最后,addAll
无论如何都必须将所有元素添加到目标集合
中。如果目标是数组列表
,则主要好处是确保没有不必要的容量增加操作。
但是请注意,这是以创建临时数组为代价的,请参见<code>ArrayList.addAll<code>的实现。为了超过这一费用,您必须添加大量元素。
如果我们要添加比目标当前容量更多的元素,增加操作是不可避免的。所以< code>addAll只提供一个好处,如果目标必须增加一次以上的容量,而您只需使用< code>add。由于容量增加了1.5倍,并且容量等于或高于当前大小,因此我们必须添加至少超过其当前大小一半的元素,以应对不必要的容量增加操作。
如果你真的认为这将是一个问题,很容易解决:
if(target instanceof ArrayList)
((ArrayList)target).ensureCapacity(target.size()+source.size());
source.stream().map(String::toLowerCase).forEachOrdered(target::add);
当然,在某些情况下,add
的成本要高得多,例如CopyOnWriteArrayList
。对于这种目标集合类型,首先通过收集(Collectors.toList())
收集到List
中,然后是addAll
可能是有益的。或者您创建一个简单的惰性集合
作为中间步骤:
public static <T> Collection<T> lazyCollection(Supplier<? extends Stream<T>> s) {
return new AbstractCollection<T>() {
public Iterator<T> iterator() { return s.get().iterator(); }
public int size() { return (int)s.get().count(); }
public Object[] toArray() { return s.get().toArray(); }
};
}
其可以如下使用:
target.addAll(lazyCollection(() -> source.stream().map(String::toLowerCase)));
如果一个集合在获取< code >迭代器之前首先请求< code>size(),那么这种方法会遇到两次流求值的问题,但是没有一个标准集合会这样做。它们或者使用迭代器而不依赖于预测的大小,或者求助于< code>toArray(),就像< code>ArrayList.addAll或< code > copyonwritearraylist . addall 所做的那样。
问题内容: LINQ的Java等效项是什么? 问题答案: 现在使用Java 8向我们介绍了Stream API,这在处理集合时是类似的事情,但与Linq不太一样。 如果它是您正在寻找的ORM,例如Entity Framework,那么您可以尝试Hibernate
问题内容: 我想保持我的依赖关系为最新。使用Node.js,我运行(及更高版本)。 Go mod最接近的是什么? 理想情况下,我会看到有关项目的过时依赖关系的报告(并非全部都是递归的)。谢谢 问题答案: 列出直接和间接依赖 Go 1.11模块:如何升级和降级依赖项 Wiki中对此进行了详细说明: 要查看所有直接和间接依赖项的可用次要和补丁升级,请运行。 要将当前模块的所有直接和间接依赖关系升级到最
问题内容: 有Swift的等效项吗?在中,我们通常使用: 如何在Swift中实现相同目标?我发现了一个功能: 但是,它很长,根本不方便。 问题答案: 将在斯威夫特的世界同样存在。 的,和参数均标有 该装置的同时调用该函数我们可以忽略这些参数的关键字。在这种情况下,将使用其默认值。 这得出一个结论,该方法调用可以简化为: Swift 5- 没什么变化,仍然可以这样工作。
问题内容: 在Objective-C中,我使用以下代码删除所有子视图: 但是如何迅速使用它呢?我看到苹果文档迅速使用了该方法 但是当我尝试它时,出现错误: 有什么方法可以快速删除子视图? 问题答案: 已针对Swift 2.0(Xcode 7)更新 用途: 或像这样:
问题内容: 在TSQL中,我可以声明: 在MySQL中,我无法编写相同的查询。 在MySQL中编写此查询的正确方法是什么? 问题答案: 行尾的分号。
问题内容: PHP具有 var_dump()函数,该函数输出对象的内部内容,显示对象的类型和内容。 例如: 将输出: Java中将执行相同操作的等效项是什么? 问题答案: 它不是Java中的嵌入式程序,因此您不会免费获得它。 它是通过约定而不是语言构造完成的。在所有数据传输类中(甚至 在您编写的所有类中…… ),您都应该实现一个明智的方法。因此,这里您需要在您的类中重写并返回所需的状态。 有一些实