Java Collection Performance Question

I created a method that takes two Collection<String>as input and copies one to the other.

However, I'm not sure if I should check if the collections contain the same elements before starting the copy, or if I should just copy independently. This is the method:

 /**
  * Copies from one collection to the other. Does not allow empty string. 
  * Removes duplicates.
  * Clears the too Collection first
  * @param src
  * @param dest
  */
 public static void copyStringCollectionAndRemoveDuplicates(Collection<String> src, Collection<String> dest) {
  if(src == null || dest == null)
   return;

  //Is this faster to do? Or should I just comment this block out
  if(src.containsAll(dest))
   return;

  dest.clear();
  Set<String> uniqueSet = new LinkedHashSet<String>(src.size());
  for(String f : src) 
   if(!"".equals(f)) 
    uniqueSet.add(f);

  dest.addAll(uniqueSet);
 }

Maybe faster just to remove

if(src.containsAll(dest))
    return;

Since this method will iterate over the entire collection anyway.

+5
source share
6 answers

: ! "", "contains()", . O (1) containsAll(); -)

. O (n), ( () ( ) add() ), target.containsAll() , () - .

-

void copy(source, dest) {
  bool:containsAll = true;
  foreach(String s in source) {  // iteration 1
    if (not s in dest) {         // contains() test
       containsAll=false
       break
    }
  }
  if (not containsAll) {
    foreach(String s in source) { // iteration 2
      if (not s in dest) {        // contains() test
        add s to dest
      }
    }
  }
}

dest, contains() -. , , dest ( ), contains() (2n-1) (n = ). contains() , .

2 , :

source = {"", "a", "b", "c", "c"}
dest = {"a", "b"}

-, containsAll , dest ( ;)). , {"a", "b", "c"} ( String "c" ). , Everthing dest , dest - ArrayList, {"a", "b", "a", "b", "c"}. ? :

void copy(Collection<String> in, Collection<String> out) {
  Set<String> unique = new HashSet<String>(in);
  in.remove("");
  out.addAll(unique);
}
+7

containsAll() , target , dest:
target: [a, b, c, d]
dest: [a, b, c]
target.containsAll(dest) , dest [a, b, c], [a, b, c, d].

, :

Set<String> uniqueSet = new LinkedHashSet<String>(target.size());
uniqueSet.addAll(target);
if(uniqueSet.contains(""))
    uniqueSet.remove("");

dest.addAll(uniqueSet);
+3

, . , containsAll(), , , , .

. dest? ? uniqueSet , . containsAll() ?

+2
  • . dest target . - dest source. .

  • ( , ), API . Collection uniquness , .

  • , , (, , ). , . , , /? , .

  • Collection addAll, removeAll, retainAll. ? :

    Collection<String> result = new HashSet<String> (dest);
    result.addAll (target);
    

    target.removeAll (dest);
    dest.addAll (target);
    
+1

. "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;" "" == dest; . :

Collection<String> source = new ArrayList<String>();
source.add("abc");
copyStringCollectionAndRemoveDuplicates(source, source);
System.out.println(source);

EDIT2:

, , 30% , . , dest colletion , . , 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);
}
}
+1

, , , , , , :

public static void copyStringCollectionAndRemoveDuplicates(
        Collection<String> src, Collection<String> dest) {
    if (src == dest) {
         throw new IllegalArgumentException("src == dest");
    }
    dest.clear();
    if (dest instanceof Set) {
        dest.addAll(src);
        dest.remove("");
    } else if (src instance of Set) {
        for (String s : src) {
            if (!"".equals(s)) {
                dest.add(s);
            }
        }
    } else {
        HashSet<String> tmp = new HashSet<String>(src);
        tmp.remove("");
        dest.addAll(tmp);
    }
}

:

  • This does not preserve the order of the elements in the argument srcin all cases, but the signature of the method implies that it does not matter.
  • I intentionally do not check for null. This is a mistake if you specify zero as an argument, and the right thing to do is allow the outlier NullPointerException.
  • Trying to copy a collection in itself is also a mistake.
0
source

All Articles