java基础总结08-集合

比眉伴天荒 2022-09-04 06:44 244阅读 0赞

这里写目录标题

    1. 什么叫集合
      1. 1 数组和集合的区别
    • 1.2 集合类体系结构
    • 1.3 集合体系特点
    1. Collection 集合概述和使用
    1. List集合的概述和特点
    • 3.1 List集合的特有方法
      • 3.3 LinkedList集合的特有功能
  • 4 Set集合概述和特点
    • 4.1 TreeSet集合
    • 4.2 HashSet集合
      • 4.2.1 哈希值
      • 4.2.2 哈希表结构
      • 4.2.3 HashSet集合存储学生对象并遍历
    1. Map集合概述和特点
    • 5.1 Map集合的基本功能
    • 5.2 Map集合的获取功能
    • 5.3 Map集合的遍历(方式1)
    • 5.4 Map集合的遍历(方式2)
    • 5.5 HashMap集合概述和特点
    • 5.6 HashMap集合应用案例
    • 3.TreeMap集合
      • 3.1TreeMap集合概述和特点【理解】
      • 3.2TreeMap集合应用案例一【应用】
      • 3.3TreeMap集合应用案例二【应用】
    • 5.Stream流
      • 5.1体验Stream流【理解】
      • 5.2 Stream流的常见生成方式【应用】
      • 5.3Stream流中间操作方法【应用】
      • 5.4Stream流终结操作方法【应用】
      • 5.5Stream流的收集操作【应用】
      • 5.6Stream流综合练习【应用】

1. 什么叫集合

Java集合类存放在java.util包中,是一个用来存放对象的容器。

1. 1 数组和集合的区别

  • 相同点

    都是容器,可以存储多个数据

  • 不同点

    • 数组的长度是不可变的,集合的长度是可变的(自动扩容)
    • 数组可以存基本数据类型和引用数据类型
    • 集合只能存引用数据类型,如果要存基本数据类型,需要存对应的包装类

1.2 集合类体系结构

在这里插入图片描述

1.3 集合体系特点

Collection 接口的接口 对象的集合(单列集合)

  • List 接口:元素按进入先后有序保存,可重复

    • LinkedList
      双向链表结构存储数据(数据可以在不连续的存储空间)
      查询慢,增删块
      没有同步, 线程不安全
    • ArrayList
      使用数组结构存储数据(元素空间连续)
      查询快,增删慢
      没有同步,线程不安全
    • Vector
      使用数组的方式存储数据
      查询快,增删慢
      同步,线程安全
  • Set接口 :无序,值不可以的重复,并做内部排序

    • HashSet:
      底层数据结构是哈希表(是一个元素为链表的数组)
      保证元素唯一性 =》 哈希表底层依赖两个方法:hashCode()和equals()

      • LinkedHashSet
        链表维护元素的插入顺序
    • TreeSet:
      底层为红黑二叉树(是一个自平衡的二叉树),元素排好序
      实现自然排序的方式

Map接口:键值对的集合(双列集合)

  • Hashtable
    同步,线程安全
  • HashMap
    没有同步, 线程不安全-
  • TreeMap
    红黑树对所有的key进行排序

在上方我们不断提到了数据结构,也就值得,集合的类型和底部的数据结构有关,但是我们不在本节讲,因为这个章节还挺大,请访问 java数据结构

2. Collection 集合概述和使用

  • Collection集合概述

    • 是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素
    • JDK 不提供此接口的任何直接实现.它提供更具体的子接口(如Set和List)实现
  • Collection集合常用方法






































    方法名 说明
    boolean add(E e) 添加元素
    boolean remove(Object o) 从集合中移除指定的元素
    boolean removeIf(Object o) 根据条件进行移除
    void clear() 清空集合中的元素
    boolean contains(Object o) 判断集合中是否存在指定的元素
    boolean isEmpty() 判断集合是否为空
    int size() 集合的长度,也就是集合中元素的个数

3. List集合的概述和特点

  • List集合的概述

    • 有序集合,这里的有序指的是存取顺序,因为该集合体系有索引
    • 用户可以精确控制列表中每个元素的插入位置,用户可以通过整数索引访问元素,并搜索列表中的元素
    • 与Set集合不同,列表通常允许重复的元素
  • List集合的特点

    • 存取有序
    • 可以重复
    • 有索引

3.1 List集合的特有方法


























方法名 描述
void add(int index,E element) 在此集合中的指定位置插入指定的元素
E remove(int index) 删除指定索引处的元素,返回被删除的元素
E set(int index,E element) 修改指定索引处的元素,返回被修改的元素
E get(int index) 返回指定索引处的元素

3.3 LinkedList集合的特有功能

  • 特有方法


































    方法名 说明
    public void addFirst(E e) 在该列表开头插入指定的元素
    public void addLast(E e) 将指定的元素追加到此列表的末尾
    public E getFirst() 返回此列表中的第一个元素
    public E getLast() 返回此列表中的最后一个元素
    public E removeFirst() 从此列表中删除并返回第一个元素
    public E removeLast() 从此列表中删除并返回最后一个元素

4 Set集合概述和特点

  • 不可以存储重复元素
  • 没有索引,不能使用普通for循环遍历

4.1 TreeSet集合

  • 不可以存储重复元素
  • 没有索引
  • 可以将 元素按照规则进行排序

    • TreeSet():根据其元素的自然排序进行排序
    • TreeSet(Comparator comparator) :根据指定的比较器进行排序

4.2 HashSet集合

  • 底层数据结构是哈希表
  • 存取无序
  • 不可以存储重复元素
  • 没有索引,不能使用普通for循环遍历

概念

  • HashSet底层数据结构采用哈希表实现,元素无序且唯一,线程不安全,效率高,可以存储null元素
  • 元素的唯一性是靠所存储元素类型是否重写hashCode()和equals()方法来保证的,如果没有重写这两个方法,则无法保证元素的唯一性。
  • 具体实现唯一性的比较过程:

    1. 存储元素首先会使用hash()算法函数生成一个int类型hashCode散列值,然后已经的所存储的元素的hashCode值比较,如果hashCode不相等,则所存储的两个对象一定不相等,此时存储当前的新的hashCode值处的元素对象;
    2. 如果hashCode相等,存储元素的对象还是不一定相等,此时会调用equals()方法判断两个对象的内容是否相等,如果内容相等,那么就是同一个对象

4.2.1 哈希值

  • 哈希值简介

    ​ 是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值

  • 如何获取哈希值

    ​ Object类中的public int hashCode():返回对象的哈希码值

  • 哈希值的特点

    • 同一个对象多次调用hashCode()方法返回的哈希值是相同的
    • 默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同

4.2.2 哈希表结构

  • JDK1.8以前

    ​ 数组 + 链表

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1LkbJn1W-1628690022441)(md_img/集合/14_JKD8以前哈希表.png)]

  • JDK1.8以后

    • 节点个数少于等于8个

      ​ 数组 + 链表

    • 节点个数多于8个

      ​ 数组 + 红黑树

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y76sgdc0-1628690022467)(md_img/集合/15_JKD8以后哈希表.png)]

4.2.3 HashSet集合存储学生对象并遍历

  • 案例需求

    • 创建一个存储学生对象的集合,存储多个学生对象,使用程序实现在控制台遍历该集合
    • 要求:学生对象的成员变量值相同,我们就认为是同一个对象
  • 代码实现

    学生类

    1. public class Student {
    2. private String name;
    3. private int age;
    4. public Student() {
    5. }
    6. public Student(String name, int age) {
    7. this.name = name;
    8. this.age = age;
    9. }
    10. public String getName() {
    11. return name;
    12. }
    13. public void setName(String name) {
    14. this.name = name;
    15. }
    16. public int getAge() {
    17. return age;
    18. }
    19. public void setAge(int age) {
    20. this.age = age;
    21. }
    22. @Override
    23. public boolean equals(Object o) {
    24. if (this == o) return true;
    25. if (o == null || getClass() != o.getClass()) return false;
    26. Student student = (Student) o;
    27. if (age != student.age) return false;
    28. return name != null ? name.equals(student.name) : student.name == null;
    29. }
    30. @Override
    31. public int hashCode() {
    32. int result = name != null ? name.hashCode() : 0;
    33. result = 31 * result + age;
    34. return result;
    35. }
    36. }

    测试类

    1. public class HashSetDemo02 {
    2. public static void main(String[] args) {
    3. //创建HashSet集合对象
    4. HashSet<Student> hs = new HashSet<Student>();
    5. //创建学生对象
    6. Student s1 = new Student("林青霞", 30);
    7. Student s2 = new Student("张曼玉", 35);
    8. Student s3 = new Student("王祖贤", 33);
    9. Student s4 = new Student("王祖贤", 33);
    10. //把学生添加到集合
    11. hs.add(s1);
    12. hs.add(s2);
    13. hs.add(s3);
    14. hs.add(s4);
    15. //遍历集合(增强for)
    16. for (Student s : hs) {
    17. System.out.println(s.getName() + "," + s.getAge());
    18. }
    19. }
    20. }
  • 总结

    ​ HashSet集合存储自定义类型元素,要想实现元素的唯一,要求必须重写hashCode方法和equals方法

5. Map集合概述和特点

  • Map集合概述

    1. interface Map<K,V> K:键的类型;V:值的类型
  • Map集合的特点

    • 双列集合,一个键对应一个值
    • 键不可以重复,值可以重复
  • Map集合的基本使用

    1. public class MapDemo01 {
    2. public static void main(String[] args) {
    3. //创建集合对象
    4. Map<String,String> map = new HashMap<String,String>();
    5. //V put(K key, V value) 将指定的值与该映射中的指定键相关联
    6. map.put("itheima001","林青霞");
    7. map.put("itheima002","张曼玉");
    8. map.put("itheima003","王祖贤");
    9. map.put("itheima003","柳岩");
    10. //输出集合对象
    11. System.out.println(map);
    12. }
    13. }

5.1 Map集合的基本功能

  • 方法介绍






































    方法名 说明
    V put(K key,V value) 添加元素
    V remove(Object key) 根据键删除键值对元素
    void clear() 移除所有的键值对元素
    boolean containsKey(Object key) 判断集合是否包含指定的键
    boolean containsValue(Object value) 判断集合是否包含指定的值
    boolean isEmpty() 判断集合是否为空
    int size() 集合的长度,也就是集合中键值对的个数
  • 示例代码

    1. public class MapDemo02 {
    2. public static void main(String[] args) {
    3. //创建集合对象
    4. Map<String,String> map = new HashMap<String,String>();
    5. //V put(K key,V value):添加元素
    6. map.put("张无忌","赵敏");
    7. map.put("郭靖","黄蓉");
    8. map.put("杨过","小龙女");
    9. //V remove(Object key):根据键删除键值对元素
    10. // System.out.println(map.remove("郭靖"));
    11. // System.out.println(map.remove("郭襄"));
    12. //void clear():移除所有的键值对元素
    13. // map.clear();
    14. //boolean containsKey(Object key):判断集合是否包含指定的键
    15. // System.out.println(map.containsKey("郭靖"));
    16. // System.out.println(map.containsKey("郭襄"));
    17. //boolean isEmpty():判断集合是否为空
    18. // System.out.println(map.isEmpty());
    19. //int size():集合的长度,也就是集合中键值对的个数
    20. System.out.println(map.size());
    21. //输出集合对象
    22. System.out.println(map);
    23. }
    24. }

5.2 Map集合的获取功能

  • 方法介绍


























    方法名 说明
    V get(Object key) 根据键获取值
    Set keySet() 获取所有键的集合
    Collection values() 获取所有值的集合
    Set<Map.Entry<K,V>> entrySet() 获取所有键值对对象的集合
  • 示例代码

    1. public class MapDemo03 {
    2. public static void main(String[] args) {
    3. //创建集合对象
    4. Map<String, String> map = new HashMap<String, String>();
    5. //添加元素
    6. map.put("张无忌", "赵敏");
    7. map.put("郭靖", "黄蓉");
    8. map.put("杨过", "小龙女");
    9. //V get(Object key):根据键获取值
    10. // System.out.println(map.get("张无忌"));
    11. // System.out.println(map.get("张三丰"));
    12. //Set<K> keySet():获取所有键的集合
    13. // Set<String> keySet = map.keySet();
    14. // for(String key : keySet) {
    15. // System.out.println(key);
    16. // }
    17. //Collection<V> values():获取所有值的集合
    18. Collection<String> values = map.values();
    19. for(String value : values) {
    20. System.out.println(value);
    21. }
    22. }
    23. }

5.3 Map集合的遍历(方式1)

  • 遍历思路

    • 我们刚才存储的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合

      • 把所有的丈夫给集中起来
      • 遍历丈夫的集合,获取到每一个丈夫
      • 根据丈夫去找对应的妻子
  • 步骤分析

    • 获取所有键的集合。用keySet()方法实现
    • 遍历键的集合,获取到每一个键。用增强for实现
    • 根据键去找值。用get(Object key)方法实现
  • 代码实现

    1. public class MapDemo01 {
    2. public static void main(String[] args) {
    3. //创建集合对象
    4. Map<String, String> map = new HashMap<String, String>();
    5. //添加元素
    6. map.put("张无忌", "赵敏");
    7. map.put("郭靖", "黄蓉");
    8. map.put("杨过", "小龙女");
    9. //获取所有键的集合。用keySet()方法实现
    10. Set<String> keySet = map.keySet();
    11. //遍历键的集合,获取到每一个键。用增强for实现
    12. for (String key : keySet) {
    13. //根据键去找值。用get(Object key)方法实现
    14. String value = map.get(key);
    15. System.out.println(key + "," + value);
    16. }
    17. }
    18. }

5.4 Map集合的遍历(方式2)

  • 遍历思路

    • 我们刚才存储的元素都是成对出现的,所以我们把Map看成是一个夫妻对的集合

      • 获取所有结婚证的集合
      • 遍历结婚证的集合,得到每一个结婚证
      • 根据结婚证获取丈夫和妻子
  • 步骤分析

    • 获取所有键值对对象的集合

      • Set> entrySet():获取所有键值对对象的集合
    • 遍历键值对对象的集合,得到每一个键值对对象

      • 用增强for实现,得到每一个Map.Entry
    • 根据键值对对象获取键和值

      • 用getKey()得到键
      • 用getValue()得到值
  • 代码实现

    1. public class MapDemo02 {
    2. public static void main(String[] args) {
    3. //创建集合对象
    4. Map<String, String> map = new HashMap<String, String>();
    5. //添加元素
    6. map.put("张无忌", "赵敏");
    7. map.put("郭靖", "黄蓉");
    8. map.put("杨过", "小龙女");
    9. //获取所有键值对对象的集合
    10. Set<Map.Entry<String, String>> entrySet = map.entrySet();
    11. //遍历键值对对象的集合,得到每一个键值对对象
    12. for (Map.Entry<String, String> me : entrySet) {
    13. //根据键值对对象获取键和值
    14. String key = me.getKey();
    15. String value = me.getValue();
    16. System.out.println(key + "," + value);
    17. }
    18. }
    19. }

5.5 HashMap集合概述和特点

  • HashMap底层是哈希表结构的
  • 依赖hashCode方法和equals方法保证键的唯一
  • 如果键要存储的是自定义对象,需要重写hashCode和equals方法

5.6 HashMap集合应用案例

  • 案例需求

    • 创建一个HashMap集合,键是学生对象(Student),值是居住地 (String)。存储多个元素,并遍历。
    • 要求保证键的唯一性:如果学生对象的成员变量值相同,我们就认为是同一个对象
  • 代码实现

    学生类

    1. public class Student {
    2. private String name;
    3. private int age;
    4. public Student() {
    5. }
    6. public Student(String name, int age) {
    7. this.name = name;
    8. this.age = age;
    9. }
    10. public String getName() {
    11. return name;
    12. }
    13. public void setName(String name) {
    14. this.name = name;
    15. }
    16. public int getAge() {
    17. return age;
    18. }
    19. public void setAge(int age) {
    20. this.age = age;
    21. }
    22. @Override
    23. public boolean equals(Object o) {
    24. if (this == o) return true;
    25. if (o == null || getClass() != o.getClass()) return false;
    26. Student student = (Student) o;
    27. if (age != student.age) return false;
    28. return name != null ? name.equals(student.name) : student.name == null;
    29. }
    30. @Override
    31. public int hashCode() {
    32. int result = name != null ? name.hashCode() : 0;
    33. result = 31 * result + age;
    34. return result;
    35. }
    36. }

    测试类

    1. public class HashMapDemo {
    2. public static void main(String[] args) {
    3. //创建HashMap集合对象
    4. HashMap<Student, String> hm = new HashMap<Student, String>();
    5. //创建学生对象
    6. Student s1 = new Student("林青霞", 30);
    7. Student s2 = new Student("张曼玉", 35);
    8. Student s3 = new Student("王祖贤", 33);
    9. Student s4 = new Student("王祖贤", 33);
    10. //把学生添加到集合
    11. hm.put(s1, "西安");
    12. hm.put(s2, "武汉");
    13. hm.put(s3, "郑州");
    14. hm.put(s4, "北京");
    15. //遍历集合
    16. Set<Student> keySet = hm.keySet();
    17. for (Student key : keySet) {
    18. String value = hm.get(key);
    19. System.out.println(key.getName() + "," + key.getAge() + "," + value);
    20. }
    21. }
    22. }

3.TreeMap集合

3.1TreeMap集合概述和特点【理解】

  • TreeMap底层是红黑树结构
  • 依赖自然排序或者比较器排序,对键进行排序
  • 如果键存储的是自定义对象,需要实现Comparable接口或者在创建TreeMap对象时候给出比较器排序规则

3.2TreeMap集合应用案例一【应用】

  • 案例需求

    • 创建一个TreeMap集合,键是学生对象(Student),值是籍贯(String),学生属性姓名和年龄,按照年龄进行排序并遍历
    • 要求按照学生的年龄进行排序,如果年龄相同则按照姓名进行排序
  • 代码实现

    学生类

    1. public class Student implements Comparable<Student>{
    2. private String name;
    3. private int age;
    4. public Student() {
    5. }
    6. public Student(String name, int age) {
    7. this.name = name;
    8. this.age = age;
    9. }
    10. public String getName() {
    11. return name;
    12. }
    13. public void setName(String name) {
    14. this.name = name;
    15. }
    16. public int getAge() {
    17. return age;
    18. }
    19. public void setAge(int age) {
    20. this.age = age;
    21. }
    22. @Override
    23. public String toString() {
    24. return "Student{" +
    25. "name='" + name + '\'' +
    26. ", age=" + age +
    27. '}';
    28. }
    29. @Override
    30. public int compareTo(Student o) {
    31. //按照年龄进行排序
    32. int result = o.getAge() - this.getAge();
    33. //次要条件,按照姓名排序。
    34. result = result == 0 ? o.getName().compareTo(this.getName()) : result;
    35. return result;
    36. }
    37. }

    测试类

    1. public class Test1 {
    2. public static void main(String[] args) {
    3. // 创建TreeMap集合对象
    4. TreeMap<Student,String> tm = new TreeMap<>();
    5. // 创建学生对象
    6. Student s1 = new Student("xiaohei",23);
    7. Student s2 = new Student("dapang",22);
    8. Student s3 = new Student("xiaomei",22);
    9. // 将学生对象添加到TreeMap集合中
    10. tm.put(s1,"江苏");
    11. tm.put(s2,"北京");
    12. tm.put(s3,"天津");
    13. // 遍历TreeMap集合,打印每个学生的信息
    14. tm.forEach(
    15. (Student key, String value)->{
    16. System.out.println(key + "---" + value);
    17. }
    18. );
    19. }
    20. }

3.3TreeMap集合应用案例二【应用】

  • 案例需求

    • 给定一个字符串,要求统计字符串中每个字符出现的次数。
    • 举例: 给定字符串是“aababcabcdabcde”,在控制台输出: “a(5)b(4)c(3)d(2)e(1)”
  • 代码实现

    1. public class Test2 {
    2. public static void main(String[] args) {
    3. // 给定字符串
    4. String s = "aababcabcdabcde";
    5. // 创建TreeMap集合对象,键是Character,值是Integer
    6. TreeMap<Character,Integer> tm = new TreeMap<>();
    7. //遍历字符串,得到每一个字符
    8. for (int i = 0; i < s.length(); i++) {
    9. //c依次表示字符串中的每一个字符
    10. char c = s.charAt(i);
    11. // 判断当前遍历到的字符是否在集合中出现过
    12. if(!tm.containsKey(c)){
    13. //表示当前字符是第一次出现。
    14. tm.put(c,1);
    15. }else{
    16. //存在,表示当前字符已经出现过了
    17. //先获取这个字符已经出现的次数
    18. Integer count = tm.get(c);
    19. //自增,表示这个字符又出现了依次
    20. count++;
    21. //将自增后的结果再次添加到集合中。
    22. tm.put(c,count);
    23. }
    24. }
    25. // a(5)b(4)c(3)d(2)e(1)
    26. //System.out.println(tm);
    27. tm.forEach(
    28. (Character key,Integer value)->{
    29. System.out.print(key + "(" + value + ")");
    30. }
    31. );
    32. }
    33. }

5.Stream流

5.1体验Stream流【理解】

  • 案例需求

    按照下面的要求完成集合的创建和遍历

    • 创建一个集合,存储多个字符串元素
    • 把集合中所有以”张”开头的元素存储到一个新的集合
    • 把”张”开头的集合中的长度为3的元素存储到一个新的集合
    • 遍历上一步得到的集合
  • 原始方式示例代码

    1. public class StreamDemo {
    2. public static void main(String[] args) {
    3. //创建一个集合,存储多个字符串元素
    4. ArrayList<String> list = new ArrayList<String>();
    5. list.add("林青霞");
    6. list.add("张曼玉");
    7. list.add("王祖贤");
    8. list.add("柳岩");
    9. list.add("张敏");
    10. list.add("张无忌");
    11. //把集合中所有以"张"开头的元素存储到一个新的集合
    12. ArrayList<String> zhangList = new ArrayList<String>();
    13. for(String s : list) {
    14. if(s.startsWith("张")) {
    15. zhangList.add(s);
    16. }
    17. }
    18. // System.out.println(zhangList);
    19. //把"张"开头的集合中的长度为3的元素存储到一个新的集合
    20. ArrayList<String> threeList = new ArrayList<String>();
    21. for(String s : zhangList) {
    22. if(s.length() == 3) {
    23. threeList.add(s);
    24. }
    25. }
    26. // System.out.println(threeList);
    27. //遍历上一步得到的集合
    28. for(String s : threeList) {
    29. System.out.println(s);
    30. }
    31. System.out.println("--------");
    32. //Stream流来改进
    33. // list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));
    34. list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(System.out::println);
    35. }
    36. }
  • 使用Stream流示例代码

    1. public class StreamDemo {
    2. public static void main(String[] args) {
    3. //创建一个集合,存储多个字符串元素
    4. ArrayList<String> list = new ArrayList<String>();
    5. list.add("林青霞");
    6. list.add("张曼玉");
    7. list.add("王祖贤");
    8. list.add("柳岩");
    9. list.add("张敏");
    10. list.add("张无忌");
    11. //Stream流来改进
    12. list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(System.out::println);
    13. }
    14. }
  • Stream流的好处

    • 直接阅读代码的字面意思即可完美展示无关逻辑方式的语义:获取流、过滤姓张、过滤长度为3、逐一打印
    • Stream流把真正的函数式编程风格引入到Java中
    • 代码简洁

5.2 Stream流的常见生成方式【应用】

  • Stream流的思想

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jvRQKutE-1628690022471)(md_img/集合/01_Stream流思想.png)]

  • Stream流的三类方法

    • 获取Stream流

      • 创建一条流水线,并把数据放到流水线上准备进行操作
    • 中间方法

      • 流水线上的操作
      • 一次操作完毕之后,还可以继续进行其他操作
    • 终结方法

      • 一个Stream流只能有一个终结方法
      • 是流水线上的最后一个操作
  • 生成Stream流的方式

    • Collection体系集合

      使用默认方法stream()生成流, default Stream stream()

    • Map体系集合

      把Map转成Set集合,间接的生成流

    • 数组

      通过Arrays中的静态方法stream生成流

    • 同种数据类型的多个数据

      通过Stream接口的静态方法of(T… values)生成流

  • 代码演示

    1. public class StreamDemo {
    2. public static void main(String[] args) {
    3. //Collection体系的集合可以使用默认方法stream()生成流
    4. List<String> list = new ArrayList<String>();
    5. Stream<String> listStream = list.stream();
    6. Set<String> set = new HashSet<String>();
    7. Stream<String> setStream = set.stream();
    8. //Map体系的集合间接的生成流
    9. Map<String,Integer> map = new HashMap<String, Integer>();
    10. Stream<String> keyStream = map.keySet().stream();
    11. Stream<Integer> valueStream = map.values().stream();
    12. Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream();
    13. //数组可以通过Arrays中的静态方法stream生成流
    14. String[] strArray = { "hello","world","java"};
    15. Stream<String> strArrayStream = Arrays.stream(strArray);
    16. //同种数据类型的多个数据可以通过Stream接口的静态方法of(T... values)生成流
    17. Stream<String> strArrayStream2 = Stream.of("hello", "world", "java");
    18. Stream<Integer> intStream = Stream.of(10, 20, 30);
    19. }
    20. }

5.3Stream流中间操作方法【应用】

  • 概念

    中间操作的意思是,执行完此方法之后,Stream流依然可以继续执行其他操作

  • 常见方法






























    方法名 说明
    Stream filter(Predicate predicate) 用于对流中的数据进行过滤
    Stream limit(long maxSize) 返回此流中的元素组成的流,截取前指定参数个数的数据
    Stream skip(long n) 跳过指定参数个数的数据,返回由该流的剩余元素组成的流
    static Stream concat(Stream a, Stream b) 合并a和b两个流为一个流
    Stream distinct() 返回由该流的不同元素(根据Object.equals(Object) )组成的流
  • filter代码演示

    1. public class StreamDemo01 {
    2. public static void main(String[] args) {
    3. //创建一个集合,存储多个字符串元素
    4. ArrayList<String> list = new ArrayList<String>();
    5. list.add("林青霞");
    6. list.add("张曼玉");
    7. list.add("王祖贤");
    8. list.add("柳岩");
    9. list.add("张敏");
    10. list.add("张无忌");
    11. //需求1:把list集合中以张开头的元素在控制台输出
    12. list.stream().filter(s -> s.startsWith("张")).forEach(System.out::println);
    13. System.out.println("--------");
    14. //需求2:把list集合中长度为3的元素在控制台输出
    15. list.stream().filter(s -> s.length() == 3).forEach(System.out::println);
    16. System.out.println("--------");
    17. //需求3:把list集合中以张开头的,长度为3的元素在控制台输出
    18. list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(System.out::println);
    19. }
    20. }
  • limit&skip代码演示

    1. public class StreamDemo02 {
    2. public static void main(String[] args) {
    3. //创建一个集合,存储多个字符串元素
    4. ArrayList<String> list = new ArrayList<String>();
    5. list.add("林青霞");
    6. list.add("张曼玉");
    7. list.add("王祖贤");
    8. list.add("柳岩");
    9. list.add("张敏");
    10. list.add("张无忌");
    11. //需求1:取前3个数据在控制台输出
    12. list.stream().limit(3).forEach(System.out::println);
    13. System.out.println("--------");
    14. //需求2:跳过3个元素,把剩下的元素在控制台输出
    15. list.stream().skip(3).forEach(System.out::println);
    16. System.out.println("--------");
    17. //需求3:跳过2个元素,把剩下的元素中前2个在控制台输出
    18. list.stream().skip(2).limit(2).forEach(System.out::println);
    19. }
    20. }
  • concat&distinct代码演示

    1. public class StreamDemo03 {
    2. public static void main(String[] args) {
    3. //创建一个集合,存储多个字符串元素
    4. ArrayList<String> list = new ArrayList<String>();
    5. list.add("林青霞");
    6. list.add("张曼玉");
    7. list.add("王祖贤");
    8. list.add("柳岩");
    9. list.add("张敏");
    10. list.add("张无忌");
    11. //需求1:取前4个数据组成一个流
    12. Stream<String> s1 = list.stream().limit(4);
    13. //需求2:跳过2个数据组成一个流
    14. Stream<String> s2 = list.stream().skip(2);
    15. //需求3:合并需求1和需求2得到的流,并把结果在控制台输出
    16. // Stream.concat(s1,s2).forEach(System.out::println);
    17. //需求4:合并需求1和需求2得到的流,并把结果在控制台输出,要求字符串元素不能重复
    18. Stream.concat(s1,s2).distinct().forEach(System.out::println);
    19. }
    20. }

5.4Stream流终结操作方法【应用】

  • 概念

    终结操作的意思是,执行完此方法之后,Stream流将不能再执行其他操作

  • 常见方法


















    方法名 说明
    void forEach(Consumer action) 对此流的每个元素执行操作
    long count() 返回此流中的元素数
  • 代码演示

    1. public class StreamDemo {
    2. public static void main(String[] args) {
    3. //创建一个集合,存储多个字符串元素
    4. ArrayList<String> list = new ArrayList<String>();
    5. list.add("林青霞");
    6. list.add("张曼玉");
    7. list.add("王祖贤");
    8. list.add("柳岩");
    9. list.add("张敏");
    10. list.add("张无忌");
    11. //需求1:把集合中的元素在控制台输出
    12. // list.stream().forEach(System.out::println);
    13. //需求2:统计集合中有几个以张开头的元素,并把统计结果在控制台输出
    14. long count = list.stream().filter(s -> s.startsWith("张")).count();
    15. System.out.println(count);
    16. }
    17. }

5.5Stream流的收集操作【应用】

  • 概念

    对数据使用Stream流的方式操作完毕后,可以把流中的数据收集到集合中

  • 常用方法














    方法名 说明
    R collect(Collector collector) 把结果收集到集合中
  • 工具类Collectors提供了具体的收集方式






















    方法名 说明
    public static Collector toList() 把元素收集到List集合中
    public static Collector toSet() 把元素收集到Set集合中
    public static Collector toMap(Function keyMapper,Function valueMapper) 把元素收集到Map集合中
  • 代码演示

    1. public class CollectDemo {
    2. public static void main(String[] args) {
    3. //创建List集合对象
    4. List<String> list = new ArrayList<String>();
    5. list.add("林青霞");
    6. list.add("张曼玉");
    7. list.add("王祖贤");
    8. list.add("柳岩");
    9. /* //需求1:得到名字为3个字的流 Stream<String> listStream = list.stream().filter(s -> s.length() == 3); //需求2:把使用Stream流操作完毕的数据收集到List集合中并遍历 List<String> names = listStream.collect(Collectors.toList()); for(String name : names) { System.out.println(name); } */
    10. //创建Set集合对象
    11. Set<Integer> set = new HashSet<Integer>();
    12. set.add(10);
    13. set.add(20);
    14. set.add(30);
    15. set.add(33);
    16. set.add(35);
    17. /* //需求3:得到年龄大于25的流 Stream<Integer> setStream = set.stream().filter(age -> age > 25); //需求4:把使用Stream流操作完毕的数据收集到Set集合中并遍历 Set<Integer> ages = setStream.collect(Collectors.toSet()); for(Integer age : ages) { System.out.println(age); } */
    18. //定义一个字符串数组,每一个字符串数据由姓名数据和年龄数据组合而成
    19. String[] strArray = { "林青霞,30", "张曼玉,35", "王祖贤,33", "柳岩,25"};
    20. //需求5:得到字符串中年龄数据大于28的流
    21. Stream<String> arrayStream = Stream.of(strArray).filter(s -> Integer.parseInt(s.split(",")[1]) > 28);
    22. //需求6:把使用Stream流操作完毕的数据收集到Map集合中并遍历,字符串中的姓名作键,年龄作值
    23. Map<String, Integer> map = arrayStream.collect(Collectors.toMap(s -> s.split(",")[0], s -> Integer.parseInt(s.split(",")[1])));
    24. Set<String> keySet = map.keySet();
    25. for (String key : keySet) {
    26. Integer value = map.get(key);
    27. System.out.println(key + "," + value);
    28. }
    29. }
    30. }

5.6Stream流综合练习【应用】

  • 案例需求

    现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作

    • 男演员只要名字为3个字的前三人
    • 女演员只要姓林的,并且不要第一个
    • 把过滤后的男演员姓名和女演员姓名合并到一起
    • 把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据

    演员类Actor已经提供,里面有一个成员变量,一个带参构造方法,以及成员变量对应的get/set方法

  • 代码实现

    演员类

    1. public class Actor {
    2. private String name;
    3. public Actor(String name) {
    4. this.name = name;
    5. }
    6. public String getName() {
    7. return name;
    8. }
    9. public void setName(String name) {
    10. this.name = name;
    11. }
    12. }

    测试类

    1. public class StreamTest {
    2. public static void main(String[] args) {
    3. //创建集合
    4. ArrayList<String> manList = new ArrayList<String>();
    5. manList.add("周润发");
    6. manList.add("成龙");
    7. manList.add("刘德华");
    8. manList.add("吴京");
    9. manList.add("周星驰");
    10. manList.add("李连杰");
    11. ArrayList<String> womanList = new ArrayList<String>();
    12. womanList.add("林心如");
    13. womanList.add("张曼玉");
    14. womanList.add("林青霞");
    15. womanList.add("柳岩");
    16. womanList.add("林志玲");
    17. womanList.add("王祖贤");
    18. /* //男演员只要名字为3个字的前三人 Stream<String> manStream = manList.stream().filter(s -> s.length() == 3).limit(3); //女演员只要姓林的,并且不要第一个 Stream<String> womanStream = womanList.stream().filter(s -> s.startsWith("林")).skip(1); //把过滤后的男演员姓名和女演员姓名合并到一起 Stream<String> stream = Stream.concat(manStream, womanStream); //把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据 // stream.map(Actor::new).forEach(System.out::println); stream.map(Actor::new).forEach(p -> System.out.println(p.getName())); */
    19. Stream.concat(manList.stream().filter(s -> s.length() == 3).limit(3),
    20. womanList.stream().filter(s -> s.startsWith("林")).skip(1)).map(Actor::new).
    21. forEach(p -> System.out.println(p.getName()));
    22. }
    23. }

发表评论

表情:
评论列表 (有 0 条评论,244人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java08 集合

    > 集合类是 Java 数据结构的实现。Java 的集合类是 java.util 包中的重要内容,它允许以各种方式将元素分组,并定义了各种使这些元素更容易操作的方法。Java