String source = "my name is name me and your name is her first her"; String[] words = source.split(" "); // 新手级计数器 public static void testNaive(String[] words){ HashMap<String, Integer> counter = new HashMap<String, Integer>(); for (String w : words) { if(counter.containsKey(w)){ int oldValue = counter.get(w); counter.put(w, oldValue+1); } else { counter.put(w, 1); } } }
// 可变Integer public static final class MutableInteger{ private int val; public MutableInteger(int val){ this.val = val; } public int get(){ return this.val; } public void set(int val){ this.val = val; } // 为了方便打印 public String toString() { return Integer.toString(val); } }
// 入门级计数器 public static void testBetter(String[] words){ HashMap<String, MutableInteger> counter = new HashMap<String, MutableInteger>(); for (String w : words) { if(counter.containsKey(w)){ MutableInteger oldValue = counter.get(w); oldValue.set(oldValue.get()+1); // 因为是引用,所以减少了一次HashMap查找 } else { counter.put(w, new MutableInteger(1)); } } }
public static void testEfficient(String[] words){ HashMap<String, MutableInteger> counter = new HashMap<String, MutableInteger>(); for (String w : words) { MutableInteger initValue = new MutableInteger(1); // 利用 HashMap 的put方法弹出旧值的特性 MutableInteger oldValue = counter.put(w, initValue); if(oldValue != null){ initValue.set(oldValue.get() + 1); } } }
10000000 次循环: 新手级计数器: 7726594902 入门级计数器: 6516014840 卓越级计数器: 5736574103 1000000 次循环: 新手级计数器: 777480106 入门级计数器: 642932000 卓越级计数器: 571867738 100000 次循环: 新手级计数器: 84323682 入门级计数器: 70176906 卓越级计数器: 61219664 10000 次循环: 新手级计数器: 13279550 入门级计数器: 7874100 卓越级计数器: 6460172 1000 次循环: 新手级计数器: 4542172 入门级计数器: 2933248 卓越级计数器: 992749 100 次循环: 新手级计数器: 3092325 入门级计数器: 1101695 卓越级计数器: 423942 10 次循环: 新手级计数器: 1993788 入门级计数器: 558150 卓越级计数器: 153156 1 次循环: 新手级计数器: 1625898 入门级计数器: 427494 卓越级计数器: 69473
import java.util.HashMap; public class TestCounter { public static void main(String[] args) { // 源字符串 String source = "my name is name me and your name is her first her"; // 计时,单位: 微秒 long startTime = 0; long endTime = 0; long duration = 0; // 测试次数 int loop = 1 * 10000; System.out.println(loop +" 次循环:"); startTime = System.nanoTime(); testNaive(source,loop); endTime = System.nanoTime(); duration = endTime - startTime; System.out.println("新手级计数器: " + duration); // startTime = System.nanoTime(); testBetter(source, loop); endTime = System.nanoTime(); duration = endTime - startTime; System.out.println("入门级计数器: " + duration); // startTime = System.nanoTime(); testEfficient(source, loop); endTime = System.nanoTime(); duration = endTime - startTime; System.out.println("卓越级计数器: " + duration); } // 新手级计数器 public static void testNaive(String source, int loop){ if(null == source){ return; } // String[] words = source.split(" "); for (int i = 0; i < loop; i++) { testNaive(words); } } public static void testNaive(String[] words){ HashMap<String, Integer> counter = new HashMap<String, Integer>(); for (String w : words) { if(counter.containsKey(w)){ int oldValue = counter.get(w); counter.put(w, oldValue+1); } else { counter.put(w, 1); } } } // 可变Integer public static final class MutableInteger{ private int val; public MutableInteger(int val){ this.val = val; } public int get(){ return this.val; } public void set(int val){ this.val = val; } // 为了方便打印 public String toString() { return Integer.toString(val); } } // 入门级计数器 public static void testBetter(String source, int loop){ if(null == source){ return; } // String[] words = source.split(" "); for (int i = 0; i < loop; i++) { testBetter(words); } } public static void testBetter(String[] words){ HashMap<String, MutableInteger> counter = new HashMap<String, MutableInteger>(); for (String w : words) { if(counter.containsKey(w)){ MutableInteger oldValue = counter.get(w); oldValue.set(oldValue.get()+1); // 因为是引用,所以减少了一次HashMap查找 } else { counter.put(w, new MutableInteger(1)); } } } // 卓越级计数器 public static void testEfficient(String source, int loop){ if(null == source){ return; } // String[] words = source.split(" "); for (int i = 0; i < loop; i++) { testEfficient(words); } } public static void testEfficient(String[] words){ HashMap<String, MutableInteger> counter = new HashMap<String, MutableInteger>(); for (String w : words) { MutableInteger initValue = new MutableInteger(1); // 利用 HashMap 的put方法弹出旧值的特性 MutableInteger oldValue = counter.put(w, initValue); if(oldValue != null){ initValue.set(oldValue.get() + 1); } } } }
HashMap<string, mutableinteger=""> efficientCounter2 = new HashMap<string, mutableinteger="">(); for (int i = 0; i < NUM_ITERATIONS; i++) for (String a : sArr) { MutableInteger value = efficientCounter2.get(a); if (value != null) { value.set(value.get() + 1); } else { efficientCounter2.put(a, new MutableInteger(1)); } }
HashMap<string, atomicinteger=""> atomicCounter = new HashMap<string, atomicinteger="">(); for (int i = 0; i < NUM_ITERATIONS; i++) for (String a : sArr) { AtomicInteger value = atomicCounter.get(a); if (value != null) { value.incrementAndGet(); } else { atomicCounter.put(a, new AtomicInteger(1)); } }
HashMap<string, int[]=""> intCounter = new HashMap<string, int[]="">(); for (int i = 0; i < NUM_ITERATIONS; i++) for (String a : sArr) { int[] valueWrapper = intCounter.get(a); if (valueWrapper == null) { intCounter.put(a, new int[] { 1 }); } else { valueWrapper[0]++; } }
1. Most efficient way to increment a Map value in Java.
2. HashMap.put() HashMap.put()2. HashSet vs. TreeSet vs. LinkedHashSet
3. Frequently Used Methods of Java HashMap4. Java Convert Hashtable to Treemap