code: // from gee.cs.oswego.edu/home/jsr166/jsr166
  
  package jsr166tests.loops;
  
  /*
   * Written by Doug Lea with assistance from members of JCP JSR-166
   * Expert Group and released to the public domain, as explained at
   * http://creativecommons.org/licenses/publicdomain
   */
  import java.util.*;
  import java.io.*;
  
  public class CollectionWordLoops {
  
      static final String[] WORDS_FILES = {
          "kw.txt",
          "class.txt",
          //        "dir.txt",
          //        "ids.txt",
          //        "/usr/dict/words",
      };
  
      static final int MAX_WORDS = 500000;
      static final int pinsert   = 80;
      static final int premove   = 2;
      static final int NOPS      = 100000;
      static final int numTests  = 2;
  
      public static void main(String[] args) {
          Class collectionClass = null;
          try {
              collectionClass = Class.forName(args[0]);
          } catch (ClassNotFoundException e) {
              throw new RuntimeException("Class " + args[0] + " not found.");
          }
  
          System.out.println("Testing " + collectionClass.getName());
  
          for (int s = 0; s < WORDS_FILES.length; ++s)
              tests(collectionClass, numTests, s);
  
          for (int s = WORDS_FILES.length-1; s >= 0; --s)
              tests(collectionClass, numTests, s);
  
      }
  
      static void tests(Class collectionClass, int numTests, int sizeIndex) {
          try {
              String[] key = readWords(sizeIndex);
              int size = key.length;
  
              System.out.print("n = " +LoopHelpers.rightJustify(size) +" : ");
              long least = Long.MAX_VALUE;
  
              for (int i = 0; i < numTests; ++i) {
                  Collection<String> m = newCollection(collectionClass);
                  long t = doTest(collectionClass.getName(), m, key);
                  if (t < least) least = t;
                  m.clear();
                  m = null;
              }
  
              long nano = Math.round(1000000.0 * (least) / NOPS);
              System.out.println(LoopHelpers.rightJustify(nano) + " ns per op");
          } catch (IOException ignore) {
              return; // skip test if can't read file
          }
      }
  
  
      static Collection<String> newCollection(Class cl) {
          try {
              Collection m = (Collection<String>) cl.newInstance();
              return m;
          } catch (Exception e) {
              throw new RuntimeException("Can't instantiate " + cl + ": " + e);
          }
      }
  
      static void pause() {
          try { Thread.sleep(100); }
          catch (InterruptedException ie) { return; }
      }
  
      static String[] readWords(int sizeIndex) throws IOException {
          String[] l = new String[MAX_WORDS];
          String[] array = null;
          try {
              FileReader fr = new FileReader(WORDS_FILES[sizeIndex]);
              BufferedReader reader = new BufferedReader(fr);
              int k = 0;
              for (;;) {
                  String s = reader.readLine();
                  if (s == null) break;
                  l[k++] = s;
              }
              array = new String[k];
              for (int i = 0; i < k; ++i) {
                  array[i] = l[i];
                  l[i] = null;
              }
              l = null;
              reader.close();
          }
          catch (IOException ex) {
              System.out.println("Can't read words file:" + ex);
              throw ex;
          }
          return array;
      }
  
      static long doTest(String name,
                         final Collection<String> m,
                         final String[] key) {
  
          //    System.out.print(name + "\t");
          Runner runner = new Runner(m, key);
          long startTime = System.currentTimeMillis();
          runner.run();
          long afterRun = System.currentTimeMillis();
          long runTime =  (afterRun - startTime);
          int np = runner.total;
          if (runner.total == runner.hashCode())
              System.out.println("Useless Number" + runner.total);
          int sz = runner.maxsz;
          if (sz == runner.hashCode())
              System.out.println("Useless Number" + sz);
          //        System.out.print(" m = " + sz);
          return runTime;
      }
  
  
      static class Runner implements Runnable {
          final Collection<String> collection;
          final String[] key;
          LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom();
          final int pctrem;
          final int pctins;
          int nputs = 0;
          int npgets = 0;
          int nagets = 0;
          int nremoves = 0;
          volatile int total;
          int maxsz;
  
          Runner(Collection<String> m, String[] k) {
              collection = m; key = k;
              pctrem = (int)(((long)premove * (long)(Integer.MAX_VALUE/2)) / 50);
              pctins = (int)(((long)pinsert * (long)(Integer.MAX_VALUE/2)) / 50);
          }
  
  
          int oneStep(int j) {
              int n = key.length;
              int r = rng.next() & 0x7FFFFFFF;
              int jinc = (r & 7);
              j += jinc - 3;
              if (j >= n) j -= n;
              if (j < 0) j += n;
  
              int l = n / 4 + j;
              if (l >= n) l -= n;
  
              String k = key[j];
  
              if (!collection.contains(k)) {
                  ++nagets;
                  if (r < pctins) {
                      collection.add(k);
                      ++nputs;
                      int csz = nputs - nremoves;
                      if (csz > maxsz) maxsz = csz;
                  }
              }
              else {
                  ++npgets;
                  if (r < pctrem) {
                      collection.remove(k);
                      ++nremoves;
                      j += ((r >>> 8) & 7) +  n / 2;
                      if (j >= n) j -= n;
                  }
              }
              return j;
          }
  
          public void run() {
              int j = key.length / 2;
              for (int i = 0; i < NOPS; ++i) {
                  j = oneStep(j);
              }
              total = nputs + npgets + nagets + nremoves;
          }
      }
  
  }
  