这段代码阅读起来很困难,而且效率不高。参数“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);
返回集合更高效,因为您不必先创建临时集合,然后将所有内容添加到目标集合中。
NonEmptyStringSet类型的好处是您可以继续添加字符串并仍然进行空字符串检查。
编辑1:
删除“if(src.containsAll(dest))return;”代码会在使用source == dest调用该方法时引入“错误”。结果是源将为空。例如:
Collection<String> source = new ArrayList<String>();
source.add("abc");
copyStringCollectionAndRemoveDuplicates(source, source);
System.out.println(source);
编辑2:
我进行了一个小基准测试,结果显示我的实现比你初始实现的简化版本快大约30%。对于你的初始实现,这个基准测试是最优情况,因为目标集合为空,所以不必清除它。此外,请注意我的实现使用 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);
}
}