我有一个大的ArrayList包含字符串。我想根据元素符合的条件来分割它。例如,如果ArrayList包含String,则它可以是字符串长度。什么是最有效的(而不是最简单的)方法呢?根据条件拆分1 ArrayList为多个1
['a', 'bc', 'defe', 'dsa', 'bb']
后会导致到:
['a'], ['bc', 'bb'], ['dsa'], ['defe']
我有一个大的ArrayList包含字符串。我想根据元素符合的条件来分割它。例如,如果ArrayList包含String,则它可以是字符串长度。什么是最有效的(而不是最简单的)方法呢?根据条件拆分1 ArrayList为多个1
['a', 'bc', 'defe', 'dsa', 'bb']
后会导致到:
['a'], ['bc', 'bb'], ['dsa'], ['defe']
最有效的方法就是重复原始列表只有一次。你做什么是你创造桶和添加到这些桶。
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个字符。你将不得不在位置阵列中的99个空位置和一个串100
在Java 8中,您可以用'computeIfAbsent(length,ArrayList :: new)'替换'get(length)',消除'if'语句。 ---另外,为什么你使用Iterator' while'循环而不是简单的增强'for'循环? ---合并,将你的循环减少到'for(String value:originalValues){orderedValues.computeIfAbsent(value.length(),ArrayList :: new).add(value); }' – Andreas
我试图让它更具普遍性和兼容性,但是如果他在Java 8中实现,评论中的提示将会很有帮助,谢谢! – palako
这很容易,公平高效的使用Java 8流做到这一点:如果你用这个输入运行
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
),K
是分组值的类型(例如Integer
,长度为,长度为)。
自己这样做(如answer by palako中所示)在运行时可能会稍微有效一些,但可能无法以任何方式进行处理。
与Java 8入住,这将是这样的:
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();
对于早期版本的Java,您不能使用computeIfAbsent()
,所以:
Map<Integer, List<String>> map = new HashMap<Integer, List<String>>();
for (String value : input) {
Integer length = Integer.valueOf(value.length()); // box only once
List<String> list = map.get(length);
if (list == null)
map.put(length, list = new ArrayList<String>());
list.add(value);
}
Collection<List<String>> output = map.values();
没有接近指定条件:有没有可能的优化,你必须用暴力解决。您可以稍微优化各自的数据结构,但匹配本身无法在不知道它完成的属性的情况下进行优化。 – Paul
这是什么情况?为什么'bc'和'bb'分组在一起,但'dsa'和'defe'不是? – SergeyB
@ike_love它遵循问题文本中给出的示例:它们按字符串*长度*进行分组。 – Andreas