我有一个包含字符串的大型ArrayList。我想根据元素遇到的条件将其拆分。例如,如果ArrayList包含String,则它可以是字符串长度。什么是最有效(而不是最简单)的方式?
successor()
之后会导致:
['a', 'bc', 'defe', 'dsa', 'bb']
答案 0 :(得分:2)
使用Java 8流来实现它非常容易且相当有效:
Invoice.php
如果您使用此输入运行它:
Collection<List<String>> output = input.stream()
.collect(Collectors.groupingBy(String::length))
.values();
您将获得此输出:
List<String> input = Arrays.asList("a", "bc", "defe", "dsa", "bb");
非流版本会做同样的事情,即构建[[a], [bc, bb], [dsa], [defe]]
,其中Map<K, List<V>>
是您的值类型(例如您的V
),String
是分组值的类型(例如 length 的K
)。
自己动手(如answer by palako中所示)在运行时可能会稍微提高效率,但可能无论如何都不重要。
坚持使用Java 8,就是这样:
Integer
对于早期版本的Java,您无法使用Map<Integer, List<String>> map = new HashMap<>();
for (String value : input)
map.computeIfAbsent(value.length(), ArrayList::new).add(value);
Collection<List<String>> output = map.values();
,因此:
computeIfAbsent()
答案 1 :(得分:1)
最有效的方法是只迭代原始列表一次。你所做的就是创建存储桶并添加到这些存储桶中。
public class Q1 {
public static void main(String[] args) {
String[] original = {"a","bc","defe","dsa","bb"};
List<String> originalValues = new ArrayList<String>(Arrays.asList(original));
Map<Integer, List<String>> orderedValues = new HashMap<Integer, List<String>>();
Iterator<String> it = originalValues.iterator();
while (it.hasNext()) {
String currentElement = it.next();
int length = currentElement.length();
if(!orderedValues.containsKey(length)) {
orderedValues.put(length, new ArrayList<String>());
}
orderedValues.get(length).add(currentElement);
}
System.out.println(orderedValues.values());
}
}
你可能想要使用数组而不是Map数组,并使用字符串的大小作为数组位置的索引,但是你需要注意你没有字符串的情况一定长度想象一下,在原始列表中只有一个字符串,但它有100个字符。在位置100的数组中,您将有99个空位置和一个字符串。