收集添加和删除元素时的代码改进
code improvement when collecting elements for add and removal
我制作了一个小程序用于测试,我在其中收集用于添加和删除的元素。下面是测试用例列表,其中“current”和“new”是参数,符号“=>”是添加和删除集合的预期结果:
current[] ; new[code1,code2] => add[code1,code2]
current[code1,code2] ; new[] => remove[code1,code2]
current[code1,code2] ; new[code3] => remove[code1,code2],add[code3]
current[code1,code2,code3] ; new[code1,code2] => remove[code3]
current[code1,code2] ; new[code1,code3] => remove[code2],add[code3]
下面是我的代码,它与上面的预期结果运行良好:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> currentList = new ArrayList<>();
List<String> newList = new ArrayList<>();
currentList.clear();
newList.clear();
newList.addAll(Arrays.asList("code1", "code2"));
test(currentList, newList);
currentList.clear();
newList.clear();
currentList.addAll(Arrays.asList("code1", "code2"));
test(currentList, newList);
currentList.clear();
newList.clear();
currentList.addAll(Arrays.asList("code1", "code2"));
newList.addAll(Arrays.asList("code3"));
test(currentList, newList);
currentList.clear();
newList.clear();
currentList.addAll(Arrays.asList("code1", "code2", "code3"));
newList.addAll(Arrays.asList("code1", "code2"));
test(currentList, newList);
currentList.clear();
newList.clear();
currentList.addAll(Arrays.asList("code1", "code2"));
newList.addAll(Arrays.asList("code1", "code3"));
test(currentList, newList);
}
// Test cases:
// current[] ; new[code1,code2] => add[code1,code2]
// current[code1,code2] ; new[] => remove[code1,code2]
// current[code1,code2] ; new[code3] => remove[code1,code2],add[code3]
// current[code1,code2,code3] ; new[code1,code2] => remove[code3]
// current[code1,code2] ; new[code1,code3] => remove[code2],add[code3]
public static void test(List<String> currentCodes, List<String> newCodes) {
System.out.println("current" + currentCodes + " ; new" + newCodes);
List<String> codesToRemove = new ArrayList<>();
for (String currentCode : currentCodes) {
if (!newCodes.contains(currentCode)) {
// just a note: call some service
codesToRemove.add(currentCode);
}
}
List<String> codesToAdd = new ArrayList<>();
for (String newCode : newCodes) {
if (!currentCodes.contains(newCode)) {
// just a note: call some service
codesToAdd.add(newCode);
}
}
System.out.println("removeResult" + codesToRemove);
System.out.println("addResult" + codesToAdd);
System.out.println("......................................");
}
}
我写这篇文章的原因是,我觉得在迭代和添加到集合添加和删除时,这段代码可以写得更好(例如,执行得更快)。
有什么建议吗?
一个简单的解决方案是
List<String> codesToRemove = new ArrayList<>(currentCodes);
codesToRemove.removeAll(newCodes);
List<String> codesToAdd = new ArrayList<>(newCodes);
codesToAdd.removeAll(currentCodes);
但是,和你原来的方法一样,它有很高的时间复杂度,O(n×m),这意味着,当两个列表都非常大时,它会非常低效。但它可能 运行 在很多情况下都具有合理的性能。
如果您必须考虑两个列表都可能很大的可能性,运行线性时间的解决方案是
List<String> codesToRemove, codesToAdd;
if(currentCodes.isEmpty() || newCodes.isEmpty()) { // short-cut
codesToRemove = currentCodes;
codesToAdd = newCodes;
}
else {
HashSet<String> set = new LinkedHashSet<>(currentCodes);
codesToAdd = new ArrayList<>();
for(String newObj: newCodes) if(!set.remove(newObj)) codesToAdd.add(newObj);
codesToRemove = new ArrayList<>(set);
}
如果你真的需要所有场景的最大性能,你可以为currentCodes.size() * newCodes.size()
设置一个阈值,使用零的捷径,当产品低于ArrayList
时的简单操作阈值和基于 HashSet
的解决方案,否则。
我制作了一个小程序用于测试,我在其中收集用于添加和删除的元素。下面是测试用例列表,其中“current”和“new”是参数,符号“=>”是添加和删除集合的预期结果:
current[] ; new[code1,code2] => add[code1,code2]
current[code1,code2] ; new[] => remove[code1,code2]
current[code1,code2] ; new[code3] => remove[code1,code2],add[code3]
current[code1,code2,code3] ; new[code1,code2] => remove[code3]
current[code1,code2] ; new[code1,code3] => remove[code2],add[code3]
下面是我的代码,它与上面的预期结果运行良好:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> currentList = new ArrayList<>();
List<String> newList = new ArrayList<>();
currentList.clear();
newList.clear();
newList.addAll(Arrays.asList("code1", "code2"));
test(currentList, newList);
currentList.clear();
newList.clear();
currentList.addAll(Arrays.asList("code1", "code2"));
test(currentList, newList);
currentList.clear();
newList.clear();
currentList.addAll(Arrays.asList("code1", "code2"));
newList.addAll(Arrays.asList("code3"));
test(currentList, newList);
currentList.clear();
newList.clear();
currentList.addAll(Arrays.asList("code1", "code2", "code3"));
newList.addAll(Arrays.asList("code1", "code2"));
test(currentList, newList);
currentList.clear();
newList.clear();
currentList.addAll(Arrays.asList("code1", "code2"));
newList.addAll(Arrays.asList("code1", "code3"));
test(currentList, newList);
}
// Test cases:
// current[] ; new[code1,code2] => add[code1,code2]
// current[code1,code2] ; new[] => remove[code1,code2]
// current[code1,code2] ; new[code3] => remove[code1,code2],add[code3]
// current[code1,code2,code3] ; new[code1,code2] => remove[code3]
// current[code1,code2] ; new[code1,code3] => remove[code2],add[code3]
public static void test(List<String> currentCodes, List<String> newCodes) {
System.out.println("current" + currentCodes + " ; new" + newCodes);
List<String> codesToRemove = new ArrayList<>();
for (String currentCode : currentCodes) {
if (!newCodes.contains(currentCode)) {
// just a note: call some service
codesToRemove.add(currentCode);
}
}
List<String> codesToAdd = new ArrayList<>();
for (String newCode : newCodes) {
if (!currentCodes.contains(newCode)) {
// just a note: call some service
codesToAdd.add(newCode);
}
}
System.out.println("removeResult" + codesToRemove);
System.out.println("addResult" + codesToAdd);
System.out.println("......................................");
}
}
我写这篇文章的原因是,我觉得在迭代和添加到集合添加和删除时,这段代码可以写得更好(例如,执行得更快)。 有什么建议吗?
一个简单的解决方案是
List<String> codesToRemove = new ArrayList<>(currentCodes);
codesToRemove.removeAll(newCodes);
List<String> codesToAdd = new ArrayList<>(newCodes);
codesToAdd.removeAll(currentCodes);
但是,和你原来的方法一样,它有很高的时间复杂度,O(n×m),这意味着,当两个列表都非常大时,它会非常低效。但它可能 运行 在很多情况下都具有合理的性能。
如果您必须考虑两个列表都可能很大的可能性,运行线性时间的解决方案是
List<String> codesToRemove, codesToAdd;
if(currentCodes.isEmpty() || newCodes.isEmpty()) { // short-cut
codesToRemove = currentCodes;
codesToAdd = newCodes;
}
else {
HashSet<String> set = new LinkedHashSet<>(currentCodes);
codesToAdd = new ArrayList<>();
for(String newObj: newCodes) if(!set.remove(newObj)) codesToAdd.add(newObj);
codesToRemove = new ArrayList<>(set);
}
如果你真的需要所有场景的最大性能,你可以为currentCodes.size() * newCodes.size()
设置一个阈值,使用零的捷径,当产品低于ArrayList
时的简单操作阈值和基于 HashSet
的解决方案,否则。