java集合框架(二)

Java集合框架(二)Map

什么是Map
Map是将键映射到值( key-value )的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。Map 接口提供三种collection 视图,允许以键集(keySet())、值集(values())或键-值映射关系集(entrySet())的形式查看某个映射的内容( 即获取键值对的内容 )
一.Map与Collection的区别
1.Map 存储的是键值对形式的元素,键唯一,值可以重复。
2.Collection 存储的是单列元素,子接口Set元素唯一,子接口List元素可重复。
3.Map集合的数据结构值针对键有效,跟值无关,Collection集合的数据结构是针对元素有效

二.Map泛型接口
1.插入(put、putAll())、删除(remove())
2.获取(entrySet()、get()、keySet()、size()、values())
3.判断(containsKey()、containsValue()、equals()、isEmpty())
4.清除(clear())
5.替换(replace(),replace(K key, V oldValue, V newValue)

void clear() 
          从此映射中移除所有映射关系(可选操作)。 
 boolean containsKey(Object key) 
          如果此映射包含指定键的映射关系,则返回 trueboolean containsValue(Object value) 
          如果此映射将一个或多个键映射到指定值,则返回 trueSet<Map.Entry<K,V>> entrySet() 
          返回此映射中包含的映射关系的 Set 视图。 
 boolean equals(Object o) 
          比较指定的对象与此映射是否相等。 
 V get(Object key) 
          返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。 
 int hashCode() 
          返回此映射的哈希码值。 
 boolean isEmpty() 
          如果此映射未包含键-值映射关系,则返回 trueSet<K> keySet() 
          返回此映射中包含的键的 Set 视图。 
 V put(K key, V value) 
          将指定的值与此映射中的指定键关联(可选操作)。 
 void putAll(Map<? extends K,? extends V> m) 
          从指定映射中将所有映射关系复制到此映射中(可选操作)。 
 V remove(Object key) 
          如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。 
 int size() 
          返回此映射中的键-值映射关系数。 
 Collection<V> values() 
          返回此映射中包含的值的 Collection 视图。

2.1 map 的遍历方式
方法一

1.获取所有键的集合
2.遍历键的集合,获取到每一个键
3.根据键找值

方法二

1.获取所有键值对对象的集合
2.遍历键值对对象的集合,获取到每一个键值对对象
3.根据键值对对象找键和值

下面给出一个例子:

public class MapReview {
    public static void main(String[] args) {
        Map<String, String> map=new HashMap<String, String>();
        map.put("000", "qqq");
        map.put("003", "rrr");
        map.put("001", "www");
        map.put("002", "eee");
        map.put("004", "sss");

        // System.out.println(map);  // 直接打印输出键值对

        // 遍历1 : 通过键值对对象entrySet获取键与值
        Set<Entry<String, String>> entrySet = map.entrySet();
        for (Entry<String, String> entry : entrySet) {
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println("key="+key+" value="+value);
        }
        System.out.println("-------------------");

        // 遍历2 : 通过键keySet获取值
        Set<String> keySet = map.keySet(); // 得到键的集合
        for (String key : keySet) {
            String value = map.get(key);
            System.out.println("key="+key+" value="+value);
        }
        System.out.println("-------------------");

        // 获取Map值的集合
        Collection<String> values = map.values();
        System.out.println(values);

        // 判断是否存在键和值
        System.out.println("containsKey="+map.containsKey("001"));
        System.out.println("containsKey="+map.containsValue("eee"));

        // 向Map集合添加元素时,若键存在,则返回之前与键对应的值
        String put = map.put("000", "aaa");
        System.out.println("put="+put); // output: qqq

        //  default V replace(K key, V value)
        //  替换功能,将旧值替换成新值,并返回旧值(若有的话)
        String replace = map.replace("003", "666");
        System.out.println("replace="+replace);
        System.out.println(map);

        // default boolean replace(K key, V oldValue, V newValue
        // 只有当键key存在,并且oldValue与newValue相等时,旧的值才会被替换成新的值,并且返回true
        boolean success = map.replace("004", "sss", "lll"); 
        System.out.println("replace2="+success); // output : true
    }
}

2.2 HashMap

HashMap的特点:
①键是哈希表结构,可以保证键的唯一性,
②当向已存在key的Map中添加元素时,会覆盖掉旧值,并将旧值返回。
③它允许使用 null 值和 null 键,但不保证映射的顺序,特别是它不保证该顺序恒久不变(即不会保证存储的顺序与输出的顺序恒久不变)。
与HashTable比较:
除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。
使用示例:

public class HashMapReview {
    public static void main(String[] args) {
        test1();
        test2();

    }

    /**
     * 自定义类型做key,
     * 需重写其equals和hashCode方法才能保证其key的唯一性
     */
    private static void test2() {
        HashMap<Info, String> map=new HashMap<Info, String>();
        map.put(new Info(0, "aaa"),"0000");
        map.put(new Info(1, "bbb"),"1111");
        map.put(new Info(3, "ddd"),"3333");
        map.put(new Info(0, "aaa"),"4444");
        map.put(new Info(2, "ccc"),"2222");
        printMap(map);
        // output:
//      key=Info [id=3, adress=ddd] value=3333
//      key=Info [id=2, adress=ccc] value=2222
//      key=Info [id=0, adress=aaa] value=0000
//      key=Info [id=1, adress=bbb] value=1111
//      key=Info [id=0, adress=aaa] value=4444  // 当Info没有重写equals和hashCode方法时,key出现重复元素
    }

    /**
     * String或基本数据类型的包装类做key,他们已重写了hashCode与equals方法
     * 键唯一,重复添加会替换旧值成新值
     */
    private static void test1() {
        HashMap<String, String> map=new HashMap<String, String>();
        map.put("aaa", "123");
        map.put("bbb", "789");
        map.put("aaa", "456");
        map.put("ccc", "321");
        System.out.println(map);
        // output:
//      {aaa=456, ccc=321, bbb=789}
        // 重复的键不会重新插入,只会替换旧值成新值
    }

    private static void printMap(Map<Info, String> map) {
        Set<Entry<Info, String>> entrySet = map.entrySet();
        for (Entry<Info, String> entry : entrySet) {
            System.out.println("key="+entry.getKey()+" value="+entry.getValue());
        }
    }
}

2.3LinkedHashMap
LinkedHashMap的特点:
Map接口的哈希表和链接列表实现,具有可预知的迭代顺序。此链接列表定义了迭代顺序(即存储的顺序与输出的顺序相同),该迭代顺序通常就是将键插入到映射中的顺序(插入顺序)。此实现不是同步的。
①当key为String或基本数据类型包装类,键相同自动替换旧值为新值 (因为他们已重写了hashCode与equals方法)
②当key为自定义对象,需让其重写hashCode与equals方法才能保证key的唯一性
2.4Hashtable
Hashtable的特点:
Hashtable是同步的,它不允许使用 null 值和 null 键。除此之外与HashMap大致相同。
Properties:
Properties类继承自Hashtable,表示了一个持久的属性集,由键值对(key-value)组成。
与Hashtable不同的是,Properties 属性列表中每个键及其对应值都是一个字符串,因此不推荐使用Hashtable的put方法为Properties添加属性。
2.5TreeMap
TreeMap的特点:
基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。
键值对是红黑树结构,可以保证键的排序和唯一性
此实现不是同步的
TreeMap使用示例:

public class TreeMapReview {
    public static void main(String[] args) {
        test1();
        test2();
    }

    /**
     * 自定义对象做key,需满足以下两个条件之一,否则抛出异常java.lang.ClassCastException:com.yu.bean.Info cannot be cast to java.lang.Comparable
     * ①实现Comparable接口并重写compare方法
     * ②构造TreeMap对象时,需传入Comparator
     * 当两者都有,以Comparator来排序
     */
    private static void test2() {
        TreeMap<Info, String> map=new TreeMap<Info, String>(new Comparator<Info>() {
            @Override
            public int compare(Info o1, Info o2) {
                int num = o2.getId() - o1.getId();
                num = num == 0 ? o2.getAdress().hashCode() - o1.getAdress().hashCode() : num;
                return num;
            }
        });
        map.put(new Info(000, "hhh"), "qqq");
        map.put(new Info(001, "hhh"), "aaa");
        map.put(new Info(002, "hhh"), "zzz");
        map.put(new Info(000, "hhh"), "qqq");

        System.out.println(map);
    }

    /**
     * String类型或基本类型包装类做key
     * String类实现了Comparable接口,可以进行自然排序
     */
    private static void test1() {
        TreeMap<String, String> map = new TreeMap<String, String>();
        map.put("a", "111");
        map.put("b", "123");
        map.put("c", "121");
        map.put("c", "121");

        Set<Entry<String, String>> entrySet = map.entrySet();
        for (Entry<String, String> entry : entrySet) {
            System.out.println("key=" + entry.getKey() + " value="
                    + entry.getValue());
        }
        // output:
//      key=a value=111
//      key=b value=123
//      key=c value=121
    }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值