代码难以阅读,效率不高。 “dest”参数令人困惑:它作为参数传递,然后被清除并将结果添加到其中。它是一个参数有什么意义?为什么不简单地返回一个新集合?我能看到的唯一好处是调用者可以确定集合类型。有必要吗?
我认为这段代码可以写得更清楚,也可能更高效:
public static Set<String> createSet(Collection<String> source) {
Set<String> destination = new HashSet<String>(source) {
private static final long serialVersionUID = 1L;
public boolean add(String o) {
if ("".equals(o)) {
return false;
}
return super.add(o);
}
};
return destination;
}
另一种方法是创建自己的集合类型:
public class NonEmptyStringSet extends HashSet<String> {
private static final long serialVersionUID = 1L;
public NonEmptyStringSet() {
super();
}
public NonEmptyStringSet(Collection<String> source) {
super(source);
}
public boolean add(String o) {
if ("".equals(o)) {
return false;
}
return super.add(o);
}
}
用法:
createSet(source);
new NonEmptyStringSet(source);
返回集合的性能更高,因为您不必先创建一个临时集合,然后将所有集合添加到 dest 集合中。
NonEmptyStringSet 类型的好处是您可以继续添加字符串,并且仍然可以检查空字符串。
EDIT1:
删除“if(src.containsAll(dest)) return;”代码在使用 source == dest 调用方法时引入了一个“错误”;结果是源将为空。示例:
Collection<String> source = new ArrayList<String>();
source.add("abc");
copyStringCollectionAndRemoveDuplicates(source, source);
System.out.println(source);
EDIT2:
我做了一个小型基准测试,结果表明我的实现比您的初始实现的简化版本快了大约 30%。此基准是您初始实施的最佳情况,因为 dest 集合为空,因此不必清除它。也不要认为我的实现使用 HashSet 而不是 LinkedHashSet,这使我的实现更快一些。
基准代码:
public class SimpleBenchmark {
public static void main(String[] args) {
Collection<String> source = Arrays.asList("abc", "def", "", "def", "",
"jsfldsjdlf", "jlkdsf", "dsfjljka", "sdfa", "abc", "dsljkf", "dsjfl",
"js52fldsjdlf", "jladsf", "dsfjdfgljka", "sdf123a", "adfgbc", "dslj452kf", "dsjfafl",
"js21ldsjdlf", "jlkdsvbxf", "dsfjljk342a", "sdfdsa", "abxc", "dsljkfsf", "dsjflasd4" );
int runCount = 1000000;
long start1 = System.currentTimeMillis();
for (int i = 0; i < runCount; i++) {
copyStringCollectionAndRemoveDuplicates(source, new ArrayList<String>());
}
long time1 = (System.currentTimeMillis() - start1);
System.out.println("Time 1: " + time1);
long start2 = System.currentTimeMillis();
for (int i = 0; i < runCount; i++) {
new NonEmptyStringSet(source);
}
long time2 = (System.currentTimeMillis() - start2);
System.out.println("Time 2: " + time2);
long difference = time1 - time2;
double percentage = (double)time2 / (double) time1;
System.out.println("Difference: " + difference + " percentage: " + percentage);
}
public static class NonEmptyStringSet extends HashSet<String> {
private static final long serialVersionUID = 1L;
public NonEmptyStringSet() {
}
public NonEmptyStringSet(Collection<String> source) {
super(source);
}
@Override
public boolean add(String o) {
if ("".equals(o)) {
return false;
}
return super.add(o);
}
}
public static void copyStringCollectionAndRemoveDuplicates(
Collection<String> src, Collection<String> dest) {
Set<String> uniqueSet = new LinkedHashSet<String>(src.size());
for (String f : src)
if (!"".equals(f))
uniqueSet.add(f);
dest.addAll(uniqueSet);
}
}