欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

带你从零学大数据系列之Java篇---第十九章:集合(Map+Collections)

程序员文章站 2022-07-04 16:00:50
...

课程重点:

  • Map的存储特点
  • Map的常用方法
  • Map的遍历
  • TreeMap的去重和排序(了解)
  • HashMap的去重(了解)
  • Collections工具类中常用方法

19.1. Map集合的存储特点

Map是双列集合的*接口, 这个接口并没有继承自Collection接口。

在Map中, 更多强调的是一层映射关系。 在Map中存储的数据, 是一个个的键值对(Key-Value-Pair), 键和值是一一对应的。

需要注意:
由于Map集合并没有实现Iterable接口, 因此这个集合是不能使用增强for循环遍历的。

19.2. Map API

带你从零学大数据系列之Java篇---第十九章:集合(Map+Collections)

19.3. 示例代码

import java.util.*;

/**
 * @Author 千锋大数据教学团队
 * @Company 千锋好程序员大数据
 * @Description Map API
 */
public class MapUsage {
    public static void main(String[] args) {
        // 1. 实例化一个Map集合的实现类对象,并向上转型为接口类型。
        Map<String, String> map = new HashMap<>();

        // 2. 向集合中插入数据
        String value = map.put("name", "xiaoming");
        System.out.println(value);      // 由于第一次添加这个键值对,集合中没有被覆盖的值,因此返回null
        String value2 = map.put("name", "xiaobai");
        System.out.println(value2);     // 这里是第二次设置name的值,会用xiaobai覆盖掉xiaoming,因此返回xiaoming

        // 3. 向集合中插入数据
        String value3 = map.putIfAbsent("name", "xiaohong");
        System.out.println(value3);     // 这里返回的是集合中已经存在的这个键对应的值
        String value4 = map.putIfAbsent("age", "20");
        System.out.println(value4);     // 由于这个集合中原来是没有age键存在的,所以返回的是null

        // 4. 将一个Map集合中所有的键值对添加到当前的集合中
        Map<String, String> tmp = new HashMap<>();
        tmp.put("height", "177");
        tmp.put("weight", "65");
        tmp.put("age", "30");
        map.putAll(tmp);


        // 5. 删除:通过键,删除一个键值对,并返回这个被删除的键值对中的值。
        String value5 = map.remove("weight");
        System.out.println(value5);

        // 6. 删除
        boolean value6 = map.remove("age", "30");
        System.out.println(value6);

        // 7. 清空集合
        // map.clear();

        // 8. 修改集合中的某一个键值对(通过键,修改值)
        String value7 = map.replace("name", "xiaohei");
        System.out.println(value7);     // 返回被覆盖的值
        String value8 = map.replace("age", "30");
        System.out.println(value8);     // 由于map中没有age键,因此这个返回null

        // 9. 修改: 只有当key和oldValue是匹配的情况下,才会将值修改成newValue。
        boolean value9 = map.replace("name", "xiaohei", "xiaohong");
        System.out.println(value9);

        // 10. 对集合中的元素进行批量的替换
        //     将集合中的每一个键值对,带入到BiFunction的方法中,使用接口方法的返回值替换集合中原来的值。
        map.replaceAll((k, v) -> {
            if (k.equals("height")) {
                return v + "cm";
            }
            return v;
        });

        // 11. 通过键获取值。
        String value10 = map.get("name1");
        System.out.println(value10);
        // 12. 通过键获取值,如果这个键不存在,则返回默认的值。
        String value11 = map.getOrDefault("name1","aaa");
        System.out.println(value11);

        // 13. 判断是否包含某一个键
        boolean value12 = map.containsKey("height");
        System.out.println(value12);

        boolean value13 = map.containsValue("177");
        System.out.println(value13);

        // 14. 获取由所有的键组成的Set集合
        Set<String> keys = map.keySet();
        //     获取由所有的值组成的Collection集合
        Collection<String> values = map.values();

        System.out.println(map);
    }
}

19.4. Map集合的遍历

19.4.1. 使用keySet进行遍历

  1. 可以使用keySet()方法获取到集合中所有的键。
  2. 遍历存储了所有的键的集合,依次通过键获取值。
/**
  * 1. 使用keySet进行遍历
  * @param map 需要遍历的集合
  */
 private static void keyset(Map<String, String> map) {
     // 1. 获取存储了所有的键的集合
     Set<String> keys = map.keySet();
     // 2. 遍历这个Set集合
     for (String key : keys) {
         // 2.1. 通过键获取值
         String value = map.get(key);
         // 2.2. 展示一下键和值
         System.out.println("key = " + key + ", value = " + value);
     }
 }

19.4.2. 使用forEach方法

这个forEach方法, 并不是Iterable接口中的方法。 是Map接口中定义的一个方法。 从功能上将, 与Iterable中的方法差不多。 只是在参数部分有区别。

default void forEach(BiConsumer<? super K, ? super V> action)

/**
  * 2. 使用forEach进行遍历
  * @param map 需要遍历的集合
  */
private static void forEach(Map<String, String> map) {
    map.forEach((k, v) -> {
        // k: 遍历到的每一个键
        // v: 遍历到的每一个值
        System.out.println("key = " + k + ", value = " + v);
    });
}

19.3.3. 使用EntrySet进行遍历

Entry<K, V>:

是Map中的内部接口, 用来描述集合中的每一个键值对。

/**
  * 3. 使用entrySet进行遍历
  * @param map 需要遍历的集合
  */
private static void entrySet(Map<String, String> map) {
    // 1. 获取一个存储有所有的Entry的一个Set集合
    Set<Map.Entry<String, String>> entries = map.entrySet();
    // 2. 遍历Set集合
    for (Map.Entry<String, String> entry : entries) {
        // 2.1. 获取键
        String key = entry.getKey();
        // 2.2. 获取值
        String value = entry.getValue();
        // 2.3. 展示
        System.out.println("key = " + key + ", value = " + value);
    }
}

19.5. HashMap与Hashtable的区别

  1. HashMap是线程不安全的集合, Hashtable是线程安全的集合。
  2. HashMap允许出现null键值, Hashtable是不允许的。
  3. HashMap的父类是AbstractMap, Hashtable的父类是Dictionary。
  4. HashMap的Map接口的新的实现类, 底层算法效率优于Hashtable。

19.6. 其他的实现类

  • LinkedHashMap
    • 与HashMap类似的,底层多维护了一个链表, 记录每一个键的存储顺序。 也就是说, 在LinkedHashMap中, 键值对的添加顺序可以得到保障。 类似于LinkedHashSet与HashSet。

 

  • TreeMap
    • 类似于TreeSet, 可以将存储进集合中的键值对, 按照键的大小比较规则, 进行升序排列。
    • TreeMap的排序规则, 类似于TreeSet。

19.7. Collections工具类

19.7.1. API

带你从零学大数据系列之Java篇---第十九章:集合(Map+Collections)

19.7.2. 示例代码

package day22.dCollections;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * @Description
 */
public class CollectionsUsage {
    public static void main(String[] args) {
        // 1. 实例化一个List集合对象
        List<Integer> list = new ArrayList<>();

        // 2. 添加元素
        Collections.addAll(list, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0);

        // 3. 获取一个集合中的最大值,大小比较通过元素对应的类实现的Comparable接口进行比较
        Integer max = Collections.max(list);
        //    获取一个集合中的最大值,大小比较通过第二个参数 Comparator
        Integer max2 = Collections.max(list, (i1, i2) -> i2 - i1);

        // 4. 获取一个集合中的最小值,大小比较通过元素对应的类实现的Comparable接口进行比较
        Integer min = Collections.min(list);
        //    获取一个集合中的最小值,大小比较通过第二个参数 Comparator
        Integer min2 = Collections.min(list, (i1, i2) -> i2 - i1);

        // 5. 将List集合中的数据进行随机的排列(洗牌)
        Collections.shuffle(list);

        // 6. 交换一个List集合中两个下标对应的元素
        Collections.swap(list, 0, 2);

        // 7. 将一个List集合中的元素倒序排列
        Collections.reverse(list);

        // 8. 将一个List集合进行排序,元素的大小比较规则使用元素对应的类实现的Comparable接口进行比较大小
        Collections.sort(list);
        //    将一个List集合按照指定的规则进行升序排序,基本不用,List集合中本身就有这样的排序方法
        Collections.sort(list, (i1, i2) -> i2 - i1);

        // 9. 集合中的元素拷贝,将第二个参数集合中的数据拷贝到第一个集合中
        List<Integer> copy = new ArrayList<>();
        Collections.addAll(copy, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
        Collections.copy(copy, list);

        // 10. 使用指定的数据,填充一个集合
        Collections.fill(list, 0);

        // 11. 将线程不安全的集合,转成线程安全的集合
        // Collections.synchronizedCollection()
        // Collections.synchronizedList()
        // Collections.synchronizedSet()
        // Collections.synchronizedMap()
    }
}
相关标签: 个人技术分享