【Java学习】Map集合&Stream流

一、Collections

1、可变参数

定义:是一种特殊形参,定义在方法、构造器的形参列表里,定义格式是:方法名(数据类型...  形参名称){  }

可变参数的特点和好处

特点:可以不传数据给它;可以传一个或者同时传多个数据给它;也可以传一个数组给它;

好处:常常用来灵活的接收数据。

注意事项

可变参数在方法内部就是一个数组

一个形参列表中可变参数只能有一个

可变参数必须放在形参列表的最后面

public class Demo {

    public static void main(String[] args) {
        add();    //可以不传递参数

    }

    public static void add(int...nums) {   //可变参数必须写在参数列表的最后
        int sum = 0;
        for (int num : nums) {
            sum += num;
        }
        System.out.println("sum=" + sum);
    }
}

 

2、Collections

Collections是一个用来操作集合的工具类

提供的常用静态方法:

方法名说明

public static <T> boolean addAll(Collection<? super T> c, T... elements)

给传入的集合批量添加元素
public static void shuffle(List<?> list)打乱List集合中的元素顺序
public static <T> void sort(List<T> list)对List集合中的元素进行升序排序
public static <T> void sort(List<T> list,Comparator<? super T> c)对List集合中元素,按照比较器对象指定的规则进行排序

举例子:

public class Demo {
    public static void main(String[] args) {
        //static <T> boolean addAll(单列集合,可变参数)   批量添加元素
        List<String> list = new ArrayList<>();
        Collections.addAll(list, "丁真", "雪豹", "理塘");
        System.out.println(list);
        System.out.println("==========================");

        //static void shuffle(List集合)    打乱List集合元素顺序,每次调用都会打乱
        Collections.shuffle(list);
        System.out.println(list);
        System.out.println("==========================");

        //static <T> void  sort(List集合)   List集合进行自然排序
        List<Integer> nums = new ArrayList<>();
        Collections.addAll(nums, 99, 55, 67, 3);
        Collections.sort(nums);
        System.out.println(nums);
        System.out.println("==========================");

        //排自定义类对象,需要指定排序规则
        List<Student> stuList = new ArrayList<>();
        stuList.add(new Student("zhangsan", 18));
        stuList.add(new Student("wangwu", 22));
        stuList.add(new Student("zhaoliu", 21));
        stuList.add(new Student("lisi", 19));
        stuList.add(new Student("qianqi", 20));

        //static<T> void sort(List集合,比较器);List集合进行比较器排序
        Collections.sort(stuList, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getAge() - o2.getAge(); //按照年龄age从小到大排列
            }
        });
        for (Student student : stuList) {
            System.out.println(student);
        }

    }
}


class Student { ... }

输出效果 

二、Map集合

1、概述

  • Map集合称为双列集合,一次需要存一对数据做为一个元素,格式:{key1=value1 , key2=value2 , key3=value3 , ...} 
  • Map集合的每个元素分为两部分:key和value,key称为键,value称为值,整体叫键值对,因此Map也叫“键值对集合”
  • Map集合的所有键是不允许重复的,但值可以重复,键和值是一一对应的,每一个键只能找到自己对应的值

在需要存储一一对应的数据时,就可以考虑使用Map集合来做,例如购物网站中,商品编号和商品数量一一对应

Map集合体系

Map集合体系的特点

注意:Map系列集合的特点都是由键决定的,值只是一个附属品,值是不做要求的

  • HashMap: 无序、不重复  (用的最多)
  • LinkedHashMap :有序、不重复
  • TreeMap: 按照大小默认升序排序、不重复

2、常用方法

  • Map是双列集合的祖宗,它的功能是全部双列集合都可以继承过来使用的。

Map常用方法:

方法名说明
public V put(K key,V value)添加/修改元素
public int size()获取集合的大小
public void clear()清空集合
public boolean isEmpty()判断集合是否为空
public V get(Object key)根据键获取对应值
public V remove(Object key)根据键删除整个元素
public boolean containsKey(Object key)判断是否包含某个键
public boolean containsValue(Object value)判断是否包含某个值
public Set<K> keySet()获取全部键的集合
public Collection<V> values()获取Map集合的全部值

举例子:

package com.itheima.c_map;

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

/*
Map
    双列集合根接口,它的功能是全部双列集合都可以继承过来使用的。

常用方法
    V put(K key,V value)   添加元素
    int size()	获取集合的大小
    boolean isEmpty()	判断集合是否为空,为空返回true, 反之
    V get(Object key)	根据键获取对应值
    V remove(Object key)	根据键删除整个元素
    boolean containsKey(Object key)	  判断是否包含某个键
    boolean containsValue(Object value)	  判断是否包含某个值
    Set<K> keySet()	 获取全部键的集合
    Collection<V> values()	 获取Map集合的全部值
    void clear()	清空集合
*/
public class Demo1 {
    public static void main(String[] args) {
        //用多态的方式创建一个HashMap
        Map<String,String> map = new HashMap<>();
        //向map中存入西游四人组的编号和姓名 001-玄奘  002-悟空  003-悟能  004-悟净

        //V put(K key,V value)   添加元素
        map.put("001","玄奘");
        map.put("002","悟空");
        map.put("003","悟能");
        map.put("004","吴京");
        System.out.println(map);
        System.out.println("======================");

        //int size()	获取集合的大小
        System.out.println(map.size());
        System.out.println("======================");

        //boolean isEmpty()	判断集合是否为空,为空返回true, 反之
        System.out.println(map.isEmpty());
        System.out.println("======================");

        //V get(Object key)	根据键获取对应值
        String value = map.get("004");
        System.out.println(value);
        System.out.println("======================");

        //V remove(Object key)	根据键删除整个元素
        map.remove("003");
        System.out.println(map);
        System.out.println("======================");

        //boolean containsKey(Object key)	  判断是否包含某个键
        boolean containsKey = map.containsKey("004");
        System.out.println(containsKey);
        System.out.println("======================");

        //boolean containsValue(Object value)	  判断是否包含某个值
        boolean containsValue = map.containsValue("吴京");
        System.out.println(containsValue);
        System.out.println("======================");

        //Set<K> keySet()	 获取全部键的集合
        Set<String> keys = map.keySet();
        System.out.println(keys);
        System.out.println("======================");

        //Collection<V> values()	 获取Map集合的全部值
        Collection<String> values = map.values();
        System.out.println(values);
        System.out.println("======================");
        
        //void clear()	清空集合
        map.clear();
        System.out.println(map);
    }
}

tips:map中的key没有顺序,本例中的“001”,“002”之所以输出时按照顺序排列,是因为这几组数字序号的哈希值恰好是连在一起的顺序排列,map在默认情况下根据他们的哈系值顺序添加

 输出效果

3、遍历方式

方式一

先获取Map集合全部的键,再通过遍历键来找值

//遍历方式1: 先获取Map集合全部的键,再通过遍历键来找值
private static void test1(HashMap<String, String> map) {
        Set<String> keys = map.keySet();
        for (String key : keys) {
            String value = map.get(key);
            System.out.println(key + "---" + value);
        }
    }

方式二

把“键值对”看成一个整体进行遍历

获取所有的entry对象,从里面拿到 key/value

Map提供的方法

Set<Map.Entry<K, V>> entrySet()               获取所有“键值对”的集合

Map.Entry提供的方法说明
K getKey()获取键
V getValue()获取值
//遍历方式2: 将map中的所有键值对放入一个set集合中, 然后遍历set集合拿到每个键值对, 再取里面的键值
private static void test2(HashMap<String, String> map) {
        Set<Map.Entry<String, String>> entries = map.entrySet();
        for (Map.Entry<String, String> entry : entries) {
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + "---" + value);
        }
    }

方式三

结合lambda遍历Map集合

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

 

//遍历方式3: Lambda, 使用foreach(BiConsumer bc)
    private static void test3(HashMap<String, String> map) {
        map.forEach((k, v) -> {
            System.out.println(k + "---" + v);
        });

    }

4、HashMap

前面提到HashMap的特点 :无序、不重复

底层原理

HashMap跟HashSet的底层原理是一模一样的,都是基于哈希表实现的

实际上Set系列集合的底层就是基于Map实现的,只是Set集合中的元素只要键数据,不要值数据而已。

保存数据到HashMap中,是将键和值保存Entry对象,然后基于哈希表计算将其保存到底层的数组的对应位置。

同样的,HashMap依赖hashCode方法和equals方法保证键的唯一。 如果键要存储的是自定义对象,需要重写hashCode和equals方法。、

 

5、LinkedHashMap

LinkedHashMap的特点是 : 有序、不重复

底层原理

底层数据结构依然是基于哈希表实现的,只是每个键值对元素又额外的多了一个双向链表的机制记录元素顺序(保证有序)

实际上LinkedHashSet集合的底层原理就是LinkedHashMap。

6、TreeMap

TreeMap的特点是:不重复、无索引、可排序(按照键的大小默认升序排列,只能对键排序)

底层原理

TreeMap跟TreeSet集合的底层原理是一样的,都是基于红黑树实现的排序。

TreeMap集合同样也支持两种方式来指定排序规则

  • 让类实现Comparable接口,重写比较规则
  • TreeMap集合有一个有参数构造器,支持创建Comparator比较器对象,以便用来指定比较规则

三、Stream

1、定义

Stream也叫Stream流,是Jdk8开始新增的一套API (java.util.stream.*),可以用于操作集合或者数组的数据。

优势: Stream流大量的结合了Lambda的语法风格来编程,提供了一种更加强大,更加简单的方式操作集合或者数组中的数据,代码更简洁,可读性更好(?

使用步骤:

  • 先得到集合或者数组的Stream流(获取)
  • 然后调用Stream流的方法对数据进行处理(操作)
  • 获取处理的结果(终结)

2、常用方法

获取Stream流的方法

获取单列集合 的Stream流

default Stream<E> stream​()

Collection提供的方法,获取当前集合对象的Stream流

获取数组的Stream流

public static <T> Stream<T> stream(T[] array)

Arrays提供的方法,获取当前数组的Stream流

获取零散数据的Stream流(不常用)

public static<T> Stream<T> of(T... values)

Stream类提供的方法,获取当前接收数据的Stream流

Stream常见的中间方法

中间方法指的是对stream流进行操作的方法, 他们调用完成后会返回新的Stream流,可以继续使用(支持链式编程)

Stream提供的常用中间方法说明
Stream<T> filter(Predicate<? super T> predicate)用于对流中的数据进行过滤
Stream<T> sorted()对元素进行升序排序
Stream<T> sorted​(Comparator<? super T> comparator)按照指定规则排序(老朋友比较器)
Stream<T> limit​(long maxSize)获取前几个元素
Stream<T> skip​(long n)跳过前几个元素
Stream<T> distinct​()去除流中重复的元素
<R> Stream<R> map​(Function<? super T,​? extends R> mapper)对元素进行加工,并返回对应的新流
static <T> Stream<T> concat​(Stream a, Stream b)合并a和b两个流为一个流

举例子

public class Demo {
    public static void main(String[] args) {
        List<Integer> list = List.of(61, 57, 66, 77, 88, 44, 100, 89, 97, 47, 70);
        //需求1: 找出所有及格的分数,并打印
        System.out.println("1=================");
        list.stream()
                .filter(e -> e>= 60)    //过滤操作
                .forEach(System.out::println);  //引用System.out的println方法

        //需求2: 找出所有及格的分数, 正序排列, 打印输出
        System.out.println("2=================");
        list.stream()
                .filter(e -> e >= 60)   //过滤
                .sorted()   //升序排序
                .forEach(System.out::println);
        //需求3: 找出所有及格的分数, 倒序排列, 打印输出
        System.out.println("3=================");
        list.stream()
                .filter(e -> e >= 60)
                .sorted(( o1, o2) -> o1 > o2? 1 : -1)   //自定义比较器排序,这里是定义为了降序排序
                .forEach(System.out::println);

        //需求4: 找出所有及格的分数, 倒序排列, 取前3名, 打印输出
        System.out.println("4=================");
        list.stream()
                .filter(e -> e >= 60)
                .sorted(( o1, o2) -> o1 > o2? 1 : -1)
                .limit(3)   //获取排序出之后的前3个元素
                .forEach(System.out::println);
        //需求5: 找出所有及格的分数, 倒序排列, 取前4-6名, 打印输出
        System.out.println("5=================");
        list.stream()
                .filter(e -> e >= 60)
                .sorted(( o1, o2) -> o1 > o2? 1 : -1)
                .skip(3)
                .limit(3)
                .forEach(System.out::println);

        //需求6:  找出所有及格的分数, 倒序排列, 取前4-6名, 将每个人的分数加10分, 打印输出
        System.out.println("6=================");
        list.stream()
                .filter(e -> e >= 60)
                .sorted(( o1, o2) -> o1 > o2? 1 : -1)
                .skip(3)
                .limit(3)
                .map(new Function<Integer, Object>() {
                    @Override
                    public Object apply(Integer e) {
                        return e + 10;
                    }
                })
                .forEach(System.out::println);

    }
}

Stream常见的终结方法

终结方法指的是调用完成后,不会返回新Stream了,没法继续使用流了。

它的作用是对流中的数据进行筛选(遍历、最大、最小、统计个数)

//1. 打印出集合中所有元素
        list.stream().forEach((e)->{
                    System.out.println(e);
                });

//2. 统计出   身高不足170的  人数
        long count = list.stream()
                .filter(student -> student.getHeight() < 170)
                .count();
        System.out.println("count = " + count);

 

 收集方式的终结方法

 

  • 23
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Map集合可以使用Stream进行操作。首先,我们需要创建一个Map对象。然后,我们可以使用Map接口中的entrySet()方法获取Map中的所有键值对,返回一个Set集合。接着,我们可以使用stream()方法将Set集合转换为Stream进行操作。使用Stream的过滤、映射、排序等中间操作方法可以对Map集合中的元素进行处理。最后,我们可以使用Stream的终结操作方法,如forEach()、collect()等来处理结果并获取最终的数据。在这个过程中,我们可以根据需要使用filter()方法进行过滤,使用map()方法进行映射,使用sorted()方法进行排序等。所以,通过使用Stream,我们可以更方便地对Map集合进行操作和处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [第八章_集合(3)_Map集合&Stream](https://blog.csdn.net/qq23001186/article/details/124062736)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [怎么在java 8的map中使用stream](https://download.csdn.net/download/weixin_38719719/14853217)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值