精华内容
下载资源
问答
  • 这篇博客是对Java Map对value值实现排序首先说一下如果Map对key进行从小到大默认排序是创建TreeMap对象。Map maps = new TreeMap<>();就行了。那么如何实现按value排序呢?这里使用的是java.util.Collections类...

    这篇博客是对Java Map对value值实现排序

    首先说一下如果Map对key进行从小到大默认排序是创建TreeMap对象。Map maps = new TreeMap<>();就行了。

    那么如何实现按value排序呢?

    这里使用的是java.util.Collections类实现排序,将Map转成List,再自定义比较器,代码如下:

    package day01_jichu;

    import java.util.ArrayList;

    import java.util.Collections;

    import java.util.Comparator;

    import java.util.List;

    import java.util.Map;

    import java.util.Map.Entry;

    import java.util.TreeMap;

    public class MapValSort {

    public static void main(String[] args) {

    Map maps = new TreeMap();

    maps.put("zhangsan", 22);

    maps.put("lisi", 24);

    maps.put("wangwu", 18);

    maps.put("zhaoliu", 22);

    //自定义比较器

    Comparator> valCmp = new Comparator>() {

    @Override

    public int compare(Entry o1, Entry o2) {

    // TODO Auto-generated method stub

    return o2.getValue()-o1.getValue(); // 降序排序,如果想升序就反过来

    }

    };

    //将map转成List,map的一组key,value对应list一个存储空间

    List> list = new ArrayList>(maps.entrySet()); //传入maps实体

    Collections.sort(list,valCmp); // 注意此处Collections 是java.util包下面的,传入List和自定义的valCmp比较器

    //输出map

    for(int i=0;i

    System.out.println(list.get(i).getKey() + " = " + list.get(i).getValue());

    }

    }

    }

    下面是输出结果

    cdac229630b3ba57ddc558e4e93174a3.png

    展开全文
  • 这篇博客是对Java Map对value值实现排序首先说一下如果Map对key进行从小到大默认排序是创建TreeMap对象。Map maps = new TreeMap<>();就行了。那么如何实现按value排序呢?这里使用的是java.util.Collections类...

    这篇博客是对Java Map对value值实现排序

    首先说一下如果Map对key进行从小到大默认排序是创建TreeMap对象。Map maps = new TreeMap<>();就行了。

    那么如何实现按value排序呢?

    这里使用的是java.util.Collections类实现排序,将Map转成List,再自定义比较器,代码如下:

    package day01_jichu;

    import java.util.ArrayList;

    import java.util.Collections;

    import java.util.Comparator;

    import java.util.List;

    import java.util.Map;

    import java.util.Map.Entry;

    import java.util.TreeMap;

    public class MapValSort {

    public static void main(String[] args) {

    Map maps = new TreeMap();

    maps.put("zhangsan", 22);

    maps.put("lisi", 24);

    maps.put("wangwu", 18);

    maps.put("zhaoliu", 22);

    //自定义比较器

    Comparator> valCmp = new Comparator>() {

    @Override

    public int compare(Entry o1, Entry o2) {

    // TODO Auto-generated method stub

    return o2.getValue()-o1.getValue(); // 降序排序,如果想升序就反过来

    }

    };

    //将map转成List,map的一组key,value对应list一个存储空间

    List> list = new ArrayList>(maps.entrySet()); //传入maps实体

    Collections.sort(list,valCmp); // 注意此处Collections 是java.util包下面的,传入List和自定义的valCmp比较器

    //输出map

    for(int i=0;i

    System.out.println(list.get(i).getKey() + " = " + list.get(i).getValue());

    }

    }

    }

    下面是输出结果

    cdac229630b3ba57ddc558e4e93174a3.png

    展开全文
  • 这篇博客是对Java Map对value值实现排序首先说一下如果Map对key进行从小到大默认排序是创建TreeMap对象。Map maps = new TreeMap<>();就行了。那么如何实现按value排序呢?这里使用的是java.util.Collections类...

    这篇博客是对Java Map对value值实现排序

    首先说一下如果Map对key进行从小到大默认排序是创建TreeMap对象。Map maps = new TreeMap<>();就行了。

    那么如何实现按value排序呢?

    这里使用的是java.util.Collections类实现排序,将Map转成List,再自定义比较器,代码如下:

    package day01_jichu;

    import java.util.ArrayList;

    import java.util.Collections;

    import java.util.Comparator;

    import java.util.List;

    import java.util.Map;

    import java.util.Map.Entry;

    import java.util.TreeMap;

    public class MapValSort {

    public static void main(String[] args) {

    Map maps = new TreeMap();

    maps.put("zhangsan", 22);

    maps.put("lisi", 24);

    maps.put("wangwu", 18);

    maps.put("zhaoliu", 22);

    //自定义比较器

    Comparator> valCmp = new Comparator>() {

    @Override

    public int compare(Entry o1, Entry o2) {

    // TODO Auto-generated method stub

    return o2.getValue()-o1.getValue(); // 降序排序,如果想升序就反过来

    }

    };

    //将map转成List,map的一组key,value对应list一个存储空间

    List> list = new ArrayList>(maps.entrySet()); //传入maps实体

    Collections.sort(list,valCmp); // 注意此处Collections 是java.util包下面的,传入List和自定义的valCmp比较器

    //输出map

    for(int i=0;i

    System.out.println(list.get(i).getKey() + " = " + list.get(i).getValue());

    }

    }

    }

    下面是输出结果

    cd855dba914a1f60e3f6193e08847998.png

    展开全文
  • 当key的个数不超过11且key的值不超过11时,Hashtable的存取是按照从大到小的顺序来存取的。 TreeMap 的顺序按照从小到大,LinkedHashMap的顺序有两种,一种是按插入顺序,一种是按访问顺序,取决于accessOrder是否为...

    对于HashMap、Hashtable、TreeMap、LinkedHashMap的内部排序,发现网上有很多人都理解错了。

    比如,有的人认为:

      Hashtable.keySet()          降序

      TreeMap.keySet()            升序

      HashMap.keySet()            乱序

      LinkedHashMap.keySet()      原序


    也有的人认为是keyset跟entryset的区别导致的。那么下面我就通过两种遍历方式来给大家试验一下。

    把全部要论证的问题先抛在这里,待会看代码看结果:

    1.HashMap、Hashtable、TreeMap、LinkedHashMap的内部排序

    2.分别用 keyset跟entryset遍历出来的结果有区别吗

    3.HashMap、Hashtable、TreeMap、LinkedHashMap初始默认的大小


    研究了一些天,有了些结果,都是通过代码测试出来的,亲测有效~~~   (分别对int,String进行测试,主要看key的排序)

    (终极声明,大家先不要吐槽范型的问题,我只是做个测试,不影响实际操作,谢过)


    先来重现一下网上的舆论结果,看我的代码

    package testCollections;
    
    import java.util.*;
    import java.util.Map.Entry;
    
    public class TestOfOrderOfMap {
    
    	//测试Keyset的排序
    	public void testOfKeyset(Map map, Object obj[]){
    		for(int i=0; i<obj.length; i++){
    			map.put(obj[i], obj[i]);
    		}
    		
    		if(map instanceof LinkedHashMap){//LinkedHashMap也是一种HashMap,所以对其测试要放在前面
    			System.out.println("LinkedHashMap" +": " + map);
    		}else if(map instanceof HashMap){
    			System.out.println("HashMap" +": " + map);
    		}else if(map instanceof Hashtable){
    			System.out.println("Hashtable" +": " + map);
    		}else if(map instanceof TreeMap){
    			System.out.println("TreeMap" +": " + map);
    		}
    		
    		System.out.print("key: ");
    		Iterator it =  map.keySet().iterator();
        	 <span style="white-space:pre">	</span>while (it.hasNext()) {
            	<span style="white-space:pre">	</span>Object key = it.next();
                            System.out.print(key+" ");
           <span style="white-space:pre">		</span>}		
             <span style="white-space:pre">	</span>System.out.println();
    	}
    	
    	//测试Entryset的排序
    	public void testOfEntryset(Map map, Object obj[]){
    		for(int i=0; i<obj.length; i++){
    			map.put(obj[i], obj[i]);
    		}
    
    		if(map instanceof LinkedHashMap){//LinkedHashMap也是一种HashMap,所以对其测试要放在前面
    			System.out.println("LinkedHashMap" +": " + map);
    		}else if(map instanceof HashMap){
    			System.out.println("HashMap" +": " + map);
    		}else if(map instanceof Hashtable){
    			System.out.println("Hashtable" +": " + map);
    		}else if(map instanceof TreeMap){
    			System.out.println("TreeMap" +": " + map);
    		}
    		
    		System.out.print("key: ");
    		Iterator it =  map.entrySet().iterator();
            <span style="white-space:pre">	</span>while (it.hasNext()) {
            	 <span style="white-space:pre">	</span>Entry e = (Entry) it.next();
               <span style="white-space:pre">		</span>System.out.print(e.getKey()+" ");
            <span style="white-space:pre">	</span>}
           <span style="white-space:pre">	</span>       System.out.println();
    	}
    	
    	 public static void main(String[] args) {
    		 TestOfOrderOfMap test = new TestOfOrderOfMap();
    		 
    		 HashMap hm1 = new HashMap();					//第一组集合是用来测试int类型的key
    		 Hashtable ht1 = new Hashtable();	 
    		 TreeMap tm1 = new TreeMap();
    		 LinkedHashMap lhm1 = new LinkedHashMap();		
    		 
    		 Integer a[] = new Integer[]{3, 2, 5, 1, 4};
    		 
    		 //测试Keyset中key为数字的排序
    		 System.out.println("这里是KeySet的测试:");
    		 test.testOfKeyset(hm1, a);
    		 test.testOfKeyset(ht1, a);
    		 test.testOfKeyset(tm1, a);
    		 test.testOfKeyset(lhm1, a);
    		 
    		//测试Entryset中key为数字的排序
    		 System.out.println();
    		 System.out.println("这里是EntrySet的测试:");
    		 test.testOfEntryset(hm1, a);
    		 test.testOfEntryset(ht1, a);
    		 test.testOfEntryset(tm1, a);
    		 test.testOfEntryset(lhm1, a);
    		 
    	 }
    }
    

    看结果


    图1


    大家是不是觉得就跟上面说的一样啊,博主,你逗我们的吧?

      Hashtable.keySet()          降序

      TreeMap.keySet()            升序

      HashMap.keySet()            乱序

      LinkedHashMap.keySet()      原序

    且听博主慢慢讲解噢,在这里可以肯定的是keyset 跟 entryset所遍历的结果完全是一样的,证明了第二点,那么第一点呢,

    如果我把上面的 Integer a[] = new Integer[]{3, 2, 5, 1, 4}; 改为  Integer a[] = new Integer[]{13, 2, 5, 1, 4}; 也就是把3改为了13,

    你们再看结果


    图2


    是不是想说,咦,这是什么鬼。是不是上面的论断结果是错误的了呀,

      Hashtable.keySet()          降序    //错误

      TreeMap.keySet()            升序    //正确

      HashMap.keySet()            乱序    //可以说错误,因为你还不懂它的原理

      LinkedHashMap.keySet()      原序  //可以说错误,因为你还不懂它的原理,这和LinkedHashMap的构造方法有关,后面我会说

    再来看几组结果,听我分析。(以后我只列出keyset的结果截图,因为entryset 跟 keyset一样)

    如果我把上面的 Integer a[] = new Integer[]{3, 2, 5, 1, 4}; 改为  Integer a[] = new Integer[]{16, 2, 5, 1, 4};


    图3


    如果我把上面的 Integer a[] = new Integer[]{3, 2, 5, 1, 4}; 改为  Integer a[] = new Integer[]{11, 2, 5, 1, 4};


    图4

    如果我把上面的 Integer a[] = new Integer[]{3, 2, 5, 1, 4}; 改为  Integer a[] = new Integer[]{0, 65, 3, 17, 32};


    图5


    大家看出端倪没有,是这样的,如果看过这些集合类源码的哥哥姐姐可能就会知道,它们的遍历与它们的存储有关,而存储与容器的大小有关,

    而在我们创建容器却没有指定容器大小的情况下,容器一般都会有一个默认大小,这个很好理解。

    HashMap 的默认大小为16,每次增长会加倍,Hashtable的默认大小为11,每次增长原来的2倍加1,TreeMap 跟 LinkedHashMap暂时无法确定或者说无限大,

    不过在这里不影响我们的理解。好了,HashMap是会根据key的hashCode再进行hash计算,最后散列到Entry中,看源码

     public V put(K key, V value) {
            if (key == null)
                return putForNullKey(value);
            int hash = hash(key);<span style="white-space:pre">		</span>//求key的hash值
            int i = indexFor(hash, table.length); //找准位置插下去
            for (Entry<K,V> e = table[i]; e != null; e = e.next) {
                Object k;
                if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                    V oldValue = e.value;
                    e.value = value;
                    e.recordAccess(this);
                    return oldValue;
                }
            }
    
            modCount++;
            addEntry(hash, key, value, i);//将其添加到该哈希值对应的链表中
            return null;
        }
    final int hash(Object k) {
            int h = 0;
            if (useAltHashing) {
                if (k instanceof String) {
                    return sun.misc.Hashing.stringHash32((String) k);
                }
                h = hashSeed;
            }
    
            h ^= k.hashCode();
    
            // This function ensures that hashCodes that differ only by
            // constant multiples at each bit position have a bounded
            // number of collisions (approximately 8 at default load factor).
            h ^= (h >>> 20) ^ (h >>> 12);<span style="white-space:pre">	</span>//这里很复杂,重新计算了哈希值
            return h ^ (h >>> 7) ^ (h >>> 4);
        }
    static int indexFor(int h, int length) {
            return h & (length-1);      //实际上就是求模
        }
    
    void addEntry(int hash, K key, V value, int bucketIndex) {
            if ((size >= threshold) && (null != table[bucketIndex])) {
                resize(2 * table.length);    //扩容
                hash = (null != key) ? hash(key) : 0;
                bucketIndex = indexFor(hash, table.length);// 将“key-value”插入指定位置,bucketIndex是位置索引。
            }
    
            createEntry(hash, key, value, bucketIndex);
        }
    void createEntry(int hash, K key, V value, int bucketIndex) {
            Entry<K,V> e = table[bucketIndex];
            table[bucketIndex] = new Entry<>(hash, key, value, e);// 创建Entry。将“key-value”插入指定位置。 
            size++;
        }
    取value的过程也一样,就是根据key存放的位置来取,所以说HashMap不是无序的,而是按照hash值来存取的,只不过这个hash值,我们比较难以计算出来罢了。
    有个小发现,当key的值不超过16时,HashMap的存取是按照从小到大的顺序来存取的

           图6


    至于Hashtable的存取,跟HashMap大同小异,只不过在方法前加了个synchronized同步字段,其次是hash值的计算有点小区别
    有个小发现,当key的个数不超过11且key的值不超过11时,Hashtable的存取是按照从大到小的顺序来存取的


    图7

    T

    reeMap就比较好理解了,其底层实现采用的是红黑树,key按照从小到大的顺序排好,搞定。

    LinkedHashMap这里呢,有两个顺序,一个是插入的顺序,一个是访问的顺序,取决于构造方法里面的参数accessOrder是否为true,当accessOrder为true时,遍历LinkedHashMap是按照访问顺序存储,当accessOrder为false时,LinkedHashMap是按照插入顺序存储,默认为false。看例子。

    package testCollections;
    
    import java.util.*;
    import java.util.Map.Entry;
    
    public class TestOfOrderOfMap {
    
    	public void testOfKeyset(Map map, Object obj[]){
    		for(int i=0; i<obj.length; i++){
    			map.put(obj[i], obj[i]);
    		}
    		
    		System.out.println("LinkedHashMap" +": " + map);
    		System.out.print("key: ");
    		Iterator it =  map.keySet().iterator();
        		while (it.hasNext()) {
            		Object key = it.next();
               	 System.out.print(key+" ");
           		}		
            	System.out.println();
    	}
    	
    	 public static void main(String[] args) {
    		 TestOfOrderOfMap test = new TestOfOrderOfMap();
    		 LinkedHashMap lhm1 = new LinkedHashMap();		
    		 Integer a[] = new Integer[]{7, 0, 5, 10, 17, 6, 2, 8, 3, 31};
    		
    		 test.testOfKeyset(lhm1, a);
    	 }
    }
    结果:

    图8


    插入的顺序为Integer a[] = new Integer[]{7, 0, 5, 10, 17, 6, 2, 8, 3, 31}
    打印的顺序也是 7, 0, 5, 10, 17, 6, 2, 8, 3, 31
    下面看按访问顺序的,把上面的
     LinkedHashMap lhm1 = new LinkedHashMap();	

    改为  LinkedHashMap lhm1 = new LinkedHashMap(16, 0.75f,true);全部修改如下:

    package testCollections;
    
    
    import java.util.*;
    import java.util.Map.Entry;
    
    
    public class TestOfOrderOfMap {
    
    
    <span style="white-space:pre">	</span>public void testOfKeyset(Map map, Object obj[]){
     <span style="white-space:pre">		</span>for(int i=0; i<obj.length; i++){
    <span style="white-space:pre">			</span>map.put(obj[i], obj[i]);
     <span style="white-space:pre">		</span>}
    
     <span style="white-space:pre">		</span>System.out.println("LinkedHashMap" +": " + map);
     
     <span style="white-space:pre">		</span>System.out.print("访问      " + map.get(7)+" 之后:   ");
     <span style="white-space:pre">		</span>System.out.println(map);
     <span style="white-space:pre">		</span>System.out.print("访问      " + map.get(10)+" 之后: ");
     <span style="white-space:pre">		</span>System.out.println(map);
     
     <span style="white-space:pre">		</span>System.out.print("最后key: ");
     <span style="white-space:pre">		</span>Iterator it =  map.keySet().iterator();
         <span style="white-space:pre">		</span>while (it.hasNext()) {
          <span style="white-space:pre">		</span>Object key = it.next();
                <span style="white-space:pre">	</span>System.out.print(key+" ");
            <span style="white-space:pre">	</span>} 
             <span style="white-space:pre">	</span>System.out.println();
     <span style="white-space:pre">	</span>}
     
     <span style="white-space:pre">	</span>public static void main(String[] args) {
     <span style="white-space:pre">		</span>TestOfOrderOfMap test = new TestOfOrderOfMap();
     <span style="white-space:pre">		</span>LinkedHashMap lhm1 = new LinkedHashMap(16, 0.75f,true); 
     <span style="white-space:pre">		</span>Integer a[] = new Integer[]{7, 0, 5, 10, 17, 6, 2, 8, 3, 31};
     
     <span style="white-space:pre">		</span>test.testOfKeyset(lhm1, a);
     <span style="white-space:pre">	</span>}
    }
    结果为


    图9


    分析:插入的顺序为  7, 0, 5, 10, 17, 6, 2, 8, 3, 31        map.get(7)之后,也就是访问7之后,就把7放在了链表的最末尾,也就是放在了31之后,变成了

    0,5,10,17,6,2,8,3,31,7      接着map.get(10)之后,也就是访问10之后,就把10放在了链表的最末尾,也就是7之后,变成了   0,5,17,6,2,8,3,31,7,10

    这就是按访问顺序存储,据说这样的好处就是可以实现LRU,即把所有访问过的对象放在了最后,那么没有被访问过的对象就在最前面了,当内存不够用时,

    就可以直接把前面最近最久没有使用的对象删除以接受新对象,从而实现置换。

    下面附加一个小知识,
    当构造方法的参数 accessOrder为true时,LinkedHashMap的get()方法会改变数据链表,那会有什么后果呢?先看结果


    图10


    啊哦,报错了,java.util.ConcurrentModificationException,先说明下,当用Entryset 来遍历的时候就不会有错,用keyset 遍历的时候就会有错,就是下面这段代码

     <span style="white-space:pre">		</span>Iterator it =  map.keySet().iterator();
    		while (it.hasNext()) {
        		<span style="white-space:pre">	</span>Object key = it.next();
           	 	 <span style="white-space:pre">	</span>System.out.print(key+" ");
           	 	 <span style="white-space:pre">	</span>System.out.print(map.get(key));
       		}	
    这是为什么呀,根据报错的源代码就很好理解了

      <span style="white-space:pre">	</span>nextEntry() {
                if (modCount != expectedModCount) //Entry 被修改的次数不等于它期望的被修改次数,所以抛出了ConcurrentModificationException异常
                    throw new ConcurrentModificationException();
                if (nextEntry == header)
                    throw new NoSuchElementException();
    
                Entry<K,V> e = lastReturned = nextEntry;
                nextEntry = e.after;
                return e;
            }
    因为当 accessOrder为true时,LinkedHashMap的get()方法会改变数据链表,因为每访问一次都要把这个key对应的Entry放到链表的最末尾(上面已经分析过),而Keyset 的 Iterator对象不允许我们动态去改变LinkedHashMap的数据链表结构,正如上面的源代码所说的,Entry 被修改的次数不等于它期望的被修改次数。因为本来就是排好序的了,你现在每访问一个,就把它放在最末尾,那么我接下来去找它的下一个的时候却发现原来那个已经不在了,因为这是动态发生的,谁也察觉不到,只有当访问到它的时候才发现不在那个位置了(拿上面那个例子,访问第一个位置上7的时候还是没问题的,访问完之后,把7放到最后面,原来的第二个位置对应的0,现在被顶到了第一个位置上,那么我下一轮该访问0的时候却发现0不见了,换成了5,那么是不是就应该报错呢)。现在明白了吧。就好比我用书包背十个乒乓球去体育馆打球,突然过来一个同学偷偷摸摸拿走了一个,还把一个坏了的放我书包里面,也不跟我打声招呼,我也没看见,过了一个小时,我把其中的9个乒乓球都打坏了,想拿第十个来用,发现,咦,怎么是坏的啊,谁换了我的乒乓球啊,我这时是不是该报警啊(哈哈,开个玩笑)
    那为什么accessOrder 为false时,采用keyset遍历就不会出现这种异常啊,因为为false 时,是按插入顺序存储啊,没有破坏原来的顺序啊,也就不会出现

    modCount   !=  expectdModCount 的情况了。

     那为什么entryset遍历的时候就不会出错呀?因为,keyset 只是预先把所有的key 放到了set当中,没有跟value对应起来,

    而entryset是把预先所有的Entry 都放在了set中,Entry中有key对应的value,所以key改变的时候value 也会跟着改变,就不会发现错位的情况了。

    两个的源码比较

    private class KeyIterator extends LinkedHashIterator<K> {
            public K next() { return nextEntry().getKey(); }
        }
      private class EntryIterator extends LinkedHashIterator<Map.Entry<K,V>> {
            public Map.Entry<K,V> next() { return nextEntry(); }
        }

    其中next()里面的return,在KeyIterator类中还多了一个getKey()。

    记得啊,你要犯这一个错误得要有三个条件才行呢,1,accessOrder  设为true。2,用keyset 遍历。3,使用map.get(key)方法

    到此,最开始提出的三个问题都已经解决了。


    那么回过头来,我们来测试当key为String  对象的时候又是个什么情形呢,其实也是大同小异啦

    package testCollections;
    
    import java.util.*;
    import java.util.Map.Entry;
    
    public class TestOfOrderOfMap {
    
    	public void testOfKeyset(Map map, Object obj[]){
    		for(int i=0; i<obj.length; i++){
    			map.put(obj[i], obj[i]);
    		}
    		
    		if(map instanceof LinkedHashMap){//LinkedHashMap也是一种HashMap,所以对其测试要放在前面
    			System.out.println("LinkedHashMap" +": " + map);
    		}else if(map instanceof HashMap){
    			System.out.println("HashMap" +": " + map);
    		}else if(map instanceof Hashtable){
    			System.out.println("Hashtable" +": " + map);
    		}else if(map instanceof TreeMap){
    			System.out.println("TreeMap" +": " + map);
    		}
    		
    		System.out.print("key: ");
    		Iterator it =  map.keySet().iterator();
        	 <span style="white-space:pre">	</span>while (it.hasNext()) {
            	 <span style="white-space:pre">	</span>Object key = it.next();
               	 <span style="white-space:pre">	</span>System.out.print(key+" ");
           	 <span style="white-space:pre">	</span>}		
           <span style="white-space:pre">		</span>System.out.println();
    	}
    	
    	 public static void main(String[] args) {
    		 TestOfOrderOfMap test = new TestOfOrderOfMap();
    		 
    		 HashMap hm2= new HashMap();					//第二组集合是用来测试String类型的key
    		 Hashtable ht2 = new Hashtable();	 
    		 TreeMap tm2 = new TreeMap();
    		 LinkedHashMap lhm2 = new LinkedHashMap(10, 0.75f, true);		
    		 
    		//Integer a[] = new Integer[]{7, 0, 5, 10, 17,6,2,8,3,31};
    		 String a[] = new String[]{"aa", "Ok", "YOU", "abc", "67k"};
    		 
    		 //测试Keyset中key为数字的排序
    		 System.out.println("这里是KeySet的测试:");
    		 test.testOfKeyset(hm2, a);
    		 test.testOfKeyset(ht2, a);
    		 test.testOfKeyset(tm2, a);
    		 test.testOfKeyset(lhm2, a);
    		 
    		/*//测试Entryset中key为数字的排序
    		 System.out.println();
    		 System.out.println("这里是EntrySet的测试:");
    		 test.testOfEntryset(hm2, a);
    		 test.testOfEntryset(ht2, a);
    		 test.testOfEntryset(tm2, a);
    		 test.testOfEntryset(lhm2, a);*/
    		 
    	 }
    }
    结果


      图11


    分析,HashMap 跟 Hashtable 一样都是无章可循的,根据它自己的hashCode来存储,TreeMap呢,根据key 的第一个字母进行排序,先数字到大写字母再到小写字母。

    LinkedHashMap 就还是跟上面的分析一样。完毕!



    总结:

    1、HashMap、Hashtable的存储顺序跟key 所对应的hashCode有关,但是有小规律,当key的值不超过16时,HashMap的存取是按照从小到大的顺序来存取的, 当key的个         数不超过11且key的值不超过11时,Hashtable的存取是按照从大到小的顺序来存取的。TreeMap 的顺序按照从小到大,LinkedHashMap的顺序有两种,一种是按插入顺           序,一种是按访问顺序,取决于accessOrder是否为true。

    2、keyset 跟 entryset 的遍历结果没有区别,有一点点区别是在LinkedHashMap中当按访问顺序存储时,采用keyset 遍历 get()方法会报错。

    3、HashMap 的默认大小为16,每次增长会加倍,Hashtable的默认大小为11,每次增长原来的2倍加1,TreeMap 跟 LinkedHashMap暂时无法确定或者说无限大,不过在这 里不影响我们的理解。


    天快亮了,人生第一次写这么长的博客,有什么纰漏的地方还望各位不吝赐教,毕竟一个人的思维深度是有限的,3Q噢。(还有不得不说CSDN写博客的编辑框排版很有问题)


    展开全文
  • 对map集合按照value从大到小进行排序

    千次阅读 2017-12-08 17:25:20
    概述:  基本特点:  该集合存储键值对,而且要保证键的惟一性 ... |--HashTable 底层是哈希数据表结构,不可以使用Null作为键或者值;... |--treemap 底层是二叉树结构,线程不同步,可以
  • 选择某种Map集合保存学号从1到15的学员的学号(键)和姓名(值),学号用字符串表示,输入的时候要以学号乱序的方式存入Map集合,然后按照学号从大到小的顺序将Map集合中的元素输出打印。需要自定义Map集合的比较器...
  • TreeMap

    2017-11-26 21:22:10
    然后按照学号从大到小的顺序将Map集合中的元素输出打印。 需要自定义Map集合的比较器Comparator, 因字符串对象的大小比较是按字典序, 而非对应的数值。 要求:必须使用Map集合的内部排序机制进行排序 ,不能...
  • java中集合Map中的键如果是int型,如何使它对应的值按照从大到小的顺序输出呢?关注:60答案:2mip版解决时间 2021-01-15 18:22提问者〖舉燈向ηáη〗2021-01-14 23:50最好举个例子,详细说一下……如果用TreeMap实现...
  • Map根据value排序

    2019-12-14 21:53:07
    我们经常遇到需要对Map排序的情况,一般根据key排序可以使用TreeMap来保存...分三步走,1)统计出现频率,使用Map,key为单词,value为出现频率,2)根据频率从大到小排序,3)输出频率topk的单词 话不多说,上代码...
  • Map排序(Java)

    2021-04-17 17:20:50
    Java中的Map排序问题 ...Java中的TreeMap默认是根据key值从小到大排序,当然,在构造函数中可以重写Comparator的compare方法实现key值从大到小排序。 public static void sortByKey() { TreeMap<String
  • Map 按照 value排序

    2014-03-19 10:56:09
    场景: 需要统计errorMsg的数量, 从大到小排序。 errorMsg为key, 数量为value。 按照key排序 很简单,TreeMap就ok。 按值排序就相对麻烦些了,貌似没有直接可用的数据结构能处理类似需求,需要我们自己转换...
  • 3.放TreeSet集合中的元素,等同于放到TreeMap集合key部分了 4.TreeSet集合中的元素,无序不可重复,但是可以按照元素的大小顺序自动排序 称为:可排序集合 例如:编写程序数据库中取出数据,在页面展示用户信息...
  • 1.TreeMap和TreeSet在排序时如何比较元素?Collections工具类中单sort()方法如何比较元素? TreeSet要求存放的对象所属的类必须事先Comparable接口,该接口提供了比较元素的compareTo()方法,当插入元素时会调该...
  • 1 解题思想题目要求给一个字符串,要求将字符串中的字符,按照字符出现的频率进行排序从大到小的输出(某个字符出现了多少就输出多少次,只是重组)解题方法: 1、统计 2、使用TreeMap,将相同频率的字符存在...
  • 字符串排序之一

    2018-05-31 15:08:00
    规则 1 :英文字母 A Z 排列,不区分大小写。如,输入: Type 输出: epTy规则 2 :同一个英文字母的大小写同时存在时,按照输入顺序排列。如,输入: BabA 输出: aABb规则 3 :非英文字母的其它字符保持原来...
  • 集合案例(Java)

    千次阅读 2020-01-04 11:04:19
    需求:键盘录入5个学生信息,并按总成绩从大到小的顺序排序 1.创建一个标准的学生类 package com.edu01; public class Student implements Comparable<Student>{ private String name; privat...
  • 面试问题2 统计一个字符串中单词的频率,并且频率按从大到小的顺序排列 对于第一个问题:把包含电视剧名字和集数的字符串作为key,对应的存储位置做为value 。用treemap比较合适。 对于第二个问题:单词作为key,...
  • 需求:键盘录入5个学生信息,并按总成绩从大到小的顺序排序1.创建一个标准的学生类 package com.edu01;public class Student implements Comparable<Student>{ private String name; private int chinese;
  • 思路:利用TreeMap实现key字典序,然后输出到LinkedList,然后用Comparator,实现字典值从大到小排序,但是key实现值相同的key字典序的想出的实现方法,但是一直错是返回null,不知所以。 程序: 1 class sort2...
  • 思路 1.设置一个全局表来存放每一个出现过的单词和它的...5.根据出现次数从大到小排序数据 6.打印出结果 实现 1.设置一个全局表来存放每一个出现过的单词和它的出现次数 这里用TreeMap方便我们排序 private sta...
  • Java基础、JavaWeb基础常用的框架再面试题都有完整的教程,几乎涵盖了Java后端必备的知识点。该开源仓库的文章都是我个人原创,公众号发过的技术文章(干货)也会有相关的目录整理,很多知识点我还在不停的...
  • 11.2.7有序树映射类(TreeMap)使用示例353 11.2.8枚举(Enum)使用示例355 11.2.9枚举集(EnumSet)使用示例358 11.3常用算法361 11.3.1Collections中的简单算法361 11.3.2排序362 11.3.3二分查找364 11.4...
  • 疯狂JAVA讲义

    2014-10-17 13:35:01
    学生提问:使用组合关系来实现复用时,需要创建两个Animal对象,是不是意味着使用组合关系时系统开销更? 159 5.9 初始化块 159 5.9.1 使用初始化块 160 5.9.2 初始化块和构造器 161 5.9.3 静态初始化块 162 ...
  • TreeMap 是唯一的带有 subMap()方法的 map,可以返回一个子集。 </li><li> <p>WeakHashMap 弱键映射,允许释放映射所指向的对象,是为某类特殊问题而设计的。如果映射之外没有引用指向某个“键”&...

空空如也

空空如也

1 2
收藏数 27
精华内容 10
关键字:

treemap从大到小排序