Java # The Map Interface

Map是将键映射到值的对象。映射不能包含重复的键:每个键最多可以映射到一个值。
该Map接口包括基本操作(如put、get、remove、 containsKey、containsValue、size和empty)、批量操作(如putAll和clear)和集合视图(如keySet、entrySet、 和values)的方法。Java 平台包含三个通用Map实现: HashMap、 TreeMap和 LinkedHashMap。它们的行为和性能与“设置接口”部分中所述的 HashSet、TreeSet和LinkedHashSet 完全相同

Map Interface基本函数

Map的基本函数(put, get, containsKey, containsValue, size, and isEmpty)的行为与Hashtable 中的对应的函数完全相同。
下方程序是一个单词频率表,每个单词将与其所在List中的出现的次数映射形如(单词=> 此单词的次数)

import java.util.*;

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

        // Initialize frequency table from command line
        for (String a : args) {
            Integer freq = m.get(a);
            m.put(a, (freq == null) ? 1 : freq + 1);
        }

        System.out.println(m.size() + " distinct words:");
        System.out.println(m);
    }
}

这个程序中put语句的第二个参数是一个判断表达式: (freq == null) ? 1 : freq + 1用来设置频率,单词之前从未出现过,那么频率就为 1 或者已经出现过多次,那对应次数就是对应的循环次数。假如运行以下语句:

 java Freq if it is to be it is up to me to delegate

对应的输出结果应该是:

8 distinct words:
{to=3, delegate=1, be=1, it=2, up=1, if=1, me=1, is=2}

假设您希望按字母顺序查看频率表,那么就需要将Map的实现类型从HashMap改为TreeMap,将会生成以下输出:

8 distinct words:
{be=1, delegate=1, if=1, is=2, it=2, me=1, to=3, up=1}

类似的,如果想输出表按照单词的第一次出现顺序输出,那么就需要将实现类型改为 LinkedHashMap

8 distinct words:
{if=1, it=2, is=2, to=3, be=1, up=1, me=1, delegate=1}

这种灵活性为基于接口的框架的强大提供有力的例证。
SetList 接口一样, Map也加强了对equalshashCode方法的需求,以便两个Map对象可以被进行逻辑性相等性的比较,而无需考虑其实现类型。两个Map 示例是相等的,如果他们表示相同的键值映射。

Map 接口批量操作

Map Interface Bulk Operations

  • clear 方法:删除Map中所有的映射
  • putAll 方法:和 Collection 接口的 addAll 方法类似

集合视图

Collection Views
Collection view 方法运行通过一下三种方式将一个Map视为一个Collection:

  • keySet — Map中的键集(Set 集合)
  • values — Map中值的集合,但是这个集合不是一个Set 集合,因为多个键可以指向同一个值,而一个键只能指向一个值
  • entrySet — Map中的键值对(Set集合)

Collection视图 提供了迭代 Map 的唯一方法。下面的例子说明了使用for-each迭代Map中键(keys)的标准习惯用法:

for (KeyType key : m.keySet())
    System.out.println(key);

此外用 iterator:

// Filter a map based on some 
// property of its keys.
for (Iterator<Type> it = m.keySet().iterator(); it.hasNext(); )
    if (it.next().isBogus())
        it.remove();

迭代值(values) 也是类似的,下面是迭代键值对的示例:

for (Map.Entry<KeyType, ValType> e : m.entrySet())
    System.out.println(e.getKey() + ": " + e.getValue());
  • 上面提到的所有3个集合视图,调用迭代(Iterator)中的remove方法移除Map中关联的条目;
    使用entrySet 视图在迭代期间使用Map.EntrySet的setValue方法还可以修改与键关联的值。这些也是在迭代时唯一安全修改Map的方式。
  • 集合视图也支持多种形式的元素删除:remove, removeAll, retainAll, clear ,Iterator.remove operation.

在Map或者Set 集合中,如果想对其中的元素进行操作,比如增删改,尽量不要通过for循环遍历直接进行操作,需要与Iterator搭配使用,请见例子:
以下是一个自定义删除Map中状态为declined的元素;
变量定义: Map(Topic, Set< JIdea >),

    public void removeDeclined() {
        for (Set<JIdea> ideas : pool.values()) {
            Iterator<JIdea> iterator = ideas.iterator();
            while (iterator.hasNext()) {
                JIdea jIdea = iterator.next();
                if (jIdea.isDeclined()) {
                    iterator.remove();  // 使用迭代器的 remove 方法安全删除元素
                }
            }
        }
    }

欢迎阅读,留言评论指出不足之处,如果点赞就更好了;
祝您学习愉快~😊😊😊

  • 32
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值