Java self - Collections Framework principles hashCode

Java hashCode principle

Step 1: List to find inefficiencies

Assuming that kept the no duplicate names in the List, there is no order of 2 million Hero
should name called "hero 1000000" object to find out
List of practice is carried out one by one for each traversal, until you find the name is "hero 1000000" hero.
In the worst case, we need to iterate and compare two million times in order to find the corresponding hero.
Test logic:

  1. Initialization 2 million objects to an ArrayList
  2. Scramble data container
  3. 10 times inquiry, the statistics every time consumed by
    different configuration of the computer, the time spent there is a difference. In the machine, the time spent is probably around 600 milliseconds

List looking for inefficiencies

package collection;
     
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
     
import charactor.Hero;
     
public class TestCollection {
    public static void main(String[] args) {
        List<Hero> heros = new ArrayList<Hero>();
            
        for (int j = 0; j < 2000000; j++) {
            Hero h = new Hero("Hero " + j);
            heros.add(h);
        }
            
        // 进行10次查找,观察大体的平均值
        for (int i = 0; i < 10; i++) {
            // 打乱heros中元素的顺序
            Collections.shuffle(heros);
             
            long start = System.currentTimeMillis();
     
            String target = "Hero 1000000";
     
            for (Hero hero : heros) {
                if (hero.name.equals(target)) {
                    System.out.println("找到了 hero!" );
                    break;
                }
            }
            long end = System.currentTimeMillis();
            long elapsed = end - start;
            System.out.println("一共花了:" + elapsed + " 毫秒");
        }
             
    }
}

Step 2: HashMap performance

Do the same look using HashMap

  1. Initialization 2 million objects into HashMap.
  2. Query 10 times
  3. Statistical query consumes every time
    can be observed, spend little time, time spent in less than 1 millisecond

HashMap performance

package collection;
  
import java.util.HashMap;
  
import charactor.Hero;
  
public class TestCollection {
    public static void main(String[] args) {
          
        HashMap<String,Hero> heroMap = new HashMap<String,Hero>();
        for (int j = 0; j < 2000000; j++) {
            Hero h = new Hero("Hero " + j);
            heroMap.put(h.name, h);
        }
        System.out.println("数据准备完成");
  
        for (int i = 0; i < 10; i++) {
            long start = System.currentTimeMillis();
              
            //查找名字是Hero 1000000的对象
            Hero target = heroMap.get("Hero 1000000");
            System.out.println("找到了 hero!" + target.name);
              
            long end = System.currentTimeMillis();
            long elapsed = end - start;
            System.out.println("一共花了:" + elapsed + " 毫秒");
        }
  
    }
}

Step 3: HashMap principle and dictionary

Before the commencement of HashMap explain the principle, first of all recall that we used in middle and high school English dictionary.

For example, to find a corresponding Chinese word meaning, assuming that words are Lengendary, first find Lengendary on page 555 in the directory.

Then, turn to page 555, this page has more than one word, but the amount has been very little, one by one relatively quickly locate the target word Lengendary.

555 is equivalent to the corresponding Lengendary hashcode

Step 4: Reasons excellent performance HashMap

----- ----- hashCode concept
all the objects, there is a corresponding hashcode (hash value)
such as the string "gareen" corresponds to 1001 (actually, there is ease of understanding, assume the value of )
such as string "temoo" corresponds to 1004
such as string "db" corresponds to 1008
such as string "annie" also corresponds to 1008

Data stored ----- -----
prepare an array whose length is 2000, and to set specific hashcode algorithm, such that all strings corresponding hashcode, will fall between 0-1999
to store the name of " gareen "hero, put the name of the hero and make up a key-value pair , stored in 1001 on the location of the array
to store the name" temoo "hero, hero put the store in 1004 on the location of the array
to store the name is "db" hero, hero put the store in 1008 on the location of the array
to store the name "annie" hero, however, the corresponding position "annie" the hashcode 1008 has db hero , then created here a list, then stored in the back annie db hero

----- ----- find data
such as To find gareen, first calculate "gareen" The hashcode is 1001, according to the 1001 index, to locate the array, ( targeted based on array subscript, is very fast a ) found 1001 this position only a hero, then the hero is gareen.
for example, to find annie, first calculate "annie" the hashcode is 1008, according to 1008 this index, to the array to locate, find 1008 this position has two a hero , then the names of the two heroes one by one comparison of ( the equals ), because the amount has to be compared to a lot less, you can quickly identify the target hero
this is to use hashmap query, very fast principle .

This is a space for time thinking of

Reasons excellent performance of HashMap
Step. 5: HashSet determines whether to repeat

HashSet data is not repeated, the same data can not be stored together in the end how to determine whether it is a duplicate?
According to the relationship between HashSet and HashMap, HashSet because we know there is no self-realization, but which encapsulates a HashMap, so in essence, to determine whether to repeat the HashMap key.

And then step through the learning, key whether to repeat, is judged by two steps:
hashcode whether as
if hashcode is not the same, that is a different pit , must not repeat
if hashcode same, which is in the same pit , equals also need to compare
if equals the same, then the data is repeated
if not the same as equals, the data is different.

Exercise : Custom string hashcode

The following is a way to generate hashcode String of Java API provided;

s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

s [0] represents a character
n denotes the length of the string
of this exercise is not required to understand the algorithm, but the custom hashcode a simple algorithm to calculate the hashcode arbitrary string
because String class can not be rewritten, so we returned to a String's hashcode by a static method

public static int hashcode(String)

If the string length is 0, 0 is returned.
Otherwise: After obtaining every character, converted to digital, added together, multiplied by 23

(s[0]+ s[1] + s[2] + s[3]+ s[n-1])*23.

If the value exceeds 1999, then take the remainder of 2000, guarantee falls between 0-1999.
If it is negative, the absolute value.

2-10 randomly generated unequal length string 100, the present value of the print number are acquired hashcode

The answer :
Here Insert Picture Description

package collection;
 
public class TestCollection {
     
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            int length = (int) (Math.random()*8+2);
            String str = randomString(length);
            int hashcode = hashcode(str);
            System.out.printf("%-11s的自定义hashcode是:%d%n",str,hashcode);         
        }
         
    }
 
    private static int hashcode(String str) {
        // TODO Auto-generated method stub
        if(0==str.length())
            return 0;
         
        int hashcode = 0;
        char[]cs= str.toCharArray();
        for (int i = 0; i < cs.length; i++) {
            hashcode +=cs[i];
        }
        hashcode*=23;
        //取绝对值
        hashcode = hashcode<0?0-hashcode:hashcode;
        //落在0-1999之间
        hashcode %=2000;
         
        return hashcode;
    }
     
    private static String randomString(int length) {
        String pool = "";
        for (short i = '0'; i <= '9'; i++) {
            pool += (char) i;
        }
        for (short i = 'a'; i <= 'z'; i++) {
            pool += (char) i;
        }
        for (short i = 'A'; i <= 'Z'; i++) {
            pool += (char) i;
        }
        char cs[] = new char[length];
        for (int i = 0; i < cs.length; i++) {
            int index = (int) (Math.random() * pool.length());
            cs[i] = pool.charAt(index);
        }
        String result = new String(cs);
        return result;
    }
     
}

Guess you like

Origin www.cnblogs.com/jeddzd/p/12144987.html