Collection -- Map

原创转载请注明出处:http://agilestyle.iteye.com/blog/1562357

 

Map的底层实现

数组+链表

Note:

HashSet底层也是用HashMap实现的

 

Map

映射(map)是一个存储关键字和值的关联或者说是关键字/值对的对象。给定一个关键字,可以得到它的值。关键字和值都是对象。关键字必须是唯一的。但值是可以重复的。有些映射可以接收null关键字和null值。而有的则不行。

 

Map接口映射唯一关键字到值。关键字(key)是以后用于检索值的对象。给定一个关键字和一个值,可以存储这个值到一个Map对象中。当这个值被存储以后,就可以使用它的关键字来检索它。当调用的映射中没有项存在时,其中的几种方法

会引发一个NoSuchElementException异常。而当对象与映射中的元素不兼容时,引发一个ClassCastException异常。如果试图使用映射不允许使用的null对象时,则引发一个NullPointerException异常。当试图改变一个不允许修改的映射时,则引发一个UnsupportedOperationException异常。

 

映射循环使用两个基本操作:get( )和put( )。使用put( )方法可以将一个指定了关键字和值的值加入映射。为了得到值,可以通过将关键字作为参数来调用get( )方法。调用返回该值。

MapTest01

package com.fairy.test;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class MapTest01 {
	public static void main(String[] args) {
		Map<String, String> map = new HashMap<String, String>();

		map.put("a", "aa");
		map.put("b", "bb");
		map.put("c", "cc");
		map.put("d", "dd");

		Set<String> set = map.keySet();

		for (Iterator<String> iter = set.iterator(); iter.hasNext();) {
			String key = iter.next();
			String value = map.get(key);

			System.out.println(key + "=" + value);
		}
	}
}

  

映射不是类集,但可以获得映射的类集“视图”。为了实现这种功能,可以使用entrySet( )方法,它返回一个包含了映射中元素的集合(Set)。为了得到关键字的类集“视图”,可以使用keySet( )方法。为了得到值的类集“视图”,可以使用

values( )方法。类集“视图”是将映射集成到类集框架内的手段。

 

Map.Entry接口使得可以操作映射的输入。回想由Map接口说明的entrySet( )方法,调用该方法返回一个包含映射输入的集合(Set)。这些集合元素的每一个都是一个Map.Entry对象。

MapTest02

package com.fairy.test;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class MapTest02 {
	public static void main(String[] args) {
		Map<String, String> map = new HashMap<String, String>();
		
		map.put("a", "aa");
		map.put("b", "bb");
		map.put("c", "cc");
		map.put("d", "dd");
		
		Set<Entry<String, String>> set = map.entrySet();
		
		System.out.println(set);
		
		for (Iterator<Entry<String, String>> iter = set.iterator(); iter.hasNext();) {
			Map.Entry<String, String> entry = iter.next();
			
			String key = entry.getKey();
			String value = entry.getValue();
			
			System.out.println(key + ":" + value);
		}
	}
}

 

Hashtable和HashMap的区别

主要是两点,还有一些琐碎的细节自行查看src

  • Hashtable线程安全;HashMap线程不安全
  • Hashtable的key、value都不可以为null;HashMap的key、value都可以为null

 

HashMap、LinkedHashMap、TreeMap和PriorityQueue的区别

HashMap

HashMap里面存入的键值对在取出的时候是随机的,也是我们最常用的一个Map.它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。在Map 中插入、删除和定位元素,HashMap 是最好的选择。

 

LinkedHashMap

LinkedHashMap 是HashMap的一个子类,如果需要输出的顺序和输入的相同,那么用LinkedHashMap可以实现.  (应用场景:购物车等需要顺序的)

 

TreeMap

TreeMap是基于红黑二叉树的NavigableMap的实现,取出来的是排序后的键值对。但如果要按自然顺序或自定义顺序遍历键,那么TreeMap会更好

 

PriorityQueue

PriorityQueue只保证最高或者最低优先级的元素在头部,并且是无序

package org.fool.java.test;

import java.util.*;

public class Test {
    public static void main(String[] args) {
        Map<String, String> linkedMap = new LinkedHashMap<>();
        linkedMap.put("e", "0");
        linkedMap.put("d", "1");
        linkedMap.put("c", "2");
        linkedMap.put("b", "3");
        linkedMap.put("a", "4");

        Map<String, String> hashMap = new HashMap<>();
        hashMap.put("e", "0");
        hashMap.put("d", "1");
        hashMap.put("c", "2");
        hashMap.put("b", "3");
        hashMap.put("a", "4");

        Queue<Integer> queue = new PriorityQueue<>();
        queue.add(6);
        queue.add(7);
        queue.add(8);
        queue.add(9);
        queue.add(1);
        queue.add(2);
        queue.add(3);
        queue.add(4);
        queue.add(5);

        System.out.println("LinkedHashMap: " + linkedMap);
        System.out.println("HashMap: " + hashMap);
        System.out.println("PriorityQueue: " + queue);
    }
}

Console Output


 

TreeMap排序

TreeMapTest.java

package org.fool.java.collections;

import java.util.*;

public class TreeMapTest {
    public static void main(String[] args) {
        // sort by key
        Map<String, Integer> keyMap = new TreeMap<>(
                (o1, o2) -> o2.compareTo(o1)    // sort by key desc
        );

        keyMap.put("a", 22);
        keyMap.put("b", 32);
        keyMap.put("c", 12);
        keyMap.put("d", 42);

        System.out.println(keyMap);    // {d=42, c=12, b=32, a=22}

        // sort by value
        Map<String, Integer> valueMap = new TreeMap<>();
        valueMap.put("a", 22);
        valueMap.put("b", 32);
        valueMap.put("c", 12);
        valueMap.put("d", 42);

        List<Map.Entry<String, Integer>> list = new ArrayList<>(valueMap.entrySet());
        Collections.sort(list, (o1, o2) -> o1.getValue().compareTo(o2.getValue()));     // sort by value asc

        Map<String, Integer> sortedMap = new LinkedHashMap<>();
        for (Map.Entry<String, Integer> entry : list) {
            sortedMap.put(entry.getKey(), entry.getValue());
        }

        System.out.println(sortedMap);      // {c=12, a=22, b=32, d=42}
    }
}

Note:

这个类加入了JDK8的Lambda特性来简化Comparator接口的编写

Console Output


 

使用JDK8的Stream特性重写TreeMap排序

package org.fool.java.collections;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Stream;

public class MapSortByGenericExample {
    public static void main(String[] args) {
        Map<String, Integer> unsortedMap = new HashMap<>();
        unsortedMap.put("z", 10);
        unsortedMap.put("b", 5);
        unsortedMap.put("a", 6);
        unsortedMap.put("c", 20);
        unsortedMap.put("d", 1);
        unsortedMap.put("e", 7);
        unsortedMap.put("y", 8);
        unsortedMap.put("n", 99);
        unsortedMap.put("j", 50);
        unsortedMap.put("m", 2);
        unsortedMap.put("f", 9);

        System.out.println("Original...");
        System.out.println(unsortedMap);

        System.out.println("Sort By Key...");
        Map<String, Integer> resultKey = compareByKey(unsortedMap);
        System.out.println(resultKey);

        System.out.println("Sort By Value...");
        Map<String, Integer> resultValue = compareByValue(unsortedMap);
        System.out.println(resultValue);
    }

    public static <K, V extends Comparable<? super V>> Map<K, V> compareByValue(Map<K, V> map) {

        Map<K, V> result = new LinkedHashMap<>();

        Stream<Map.Entry<K, V>> mapInStream = map.entrySet().stream();

        mapInStream.sorted(Map.Entry.comparingByValue())
                .forEachOrdered(x -> result.put(x.getKey(), x.getValue()));

        return result;
    }

    public static <K extends Comparable<? super K>, V> Map<K, V> compareByKey(Map<K, V> map) {

        Map<K, V> result = new LinkedHashMap<>();
        Stream<Map.Entry<K, V>> mapInStream = map.entrySet().stream();

        mapInStream.sorted(Map.Entry.comparingByKey())
                .forEachOrdered(x -> result.put(x.getKey(), x.getValue()));

        return result;
    }
}

Console Output


 

Reference

http://www.mkyong.com/java/how-to-sort-a-map-in-java/

http://www.mkyong.com/java8/java-8-how-to-sort-a-map/ 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值