DW-CHEN的Java点滴记录之集合/泛型/可变参数/Stream流

集合

  • 集合和数组的对比
    1.数组的长度是不可变的,集合的长度是可变的
    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()集合长度,也就是集合中元素的个数
package cn.cdw.demo;

import java.util.ArrayList;
import java.util.Collection;

/**
 * @author DW-CHEN
 * 单列集合Collection
 */
public class Demo45 {
    public static void main(String[] args) {
        Collection<Integer> collection = new ArrayList<>();

        for (int i = 1; i <= 6; i++) {
            collection.add(i);
        }
        System.out.println("添加数据后的集合:"+collection);

        System.out.println("从集合中移除指定的元素4:" + collection.remove(4) +"  "+ collection);

        boolean b = collection.removeIf((Integer i) -> {
            return i == 3;
        });
        System.out.println("根据条件进行删除,条件元素为3进行删除:" + b + " " + collection);

        System.out.println("集合中是否包含指定的元素5:" + collection.contains(5) + " " + collection);

        System.out.println("集合是否为空:" + collection.isEmpty() + " " + collection);

        System.out.println("集合长度:" + collection.size() + " " + collection);

        collection.clear();
        System.out.println("清空集合后的集合:" + collection);



    }
}
Collection集合遍历
Iterator:迭代器

Iterator< E > iterator():返回集合中的迭代器对象,该迭代器对象默认指向当前集合的0索引

Iterator常用方法

方法名说明
boolean hasNext()判断当前位置是否有元素被取出
E next()获取当前位置的元素,将迭代器对象移向下一个索引位置
package cn.cdw.demo;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * @author DW-CHEN
 * 迭代器Iterator
 */
public class Demo46 {
    public static void main(String[] args) {
        Collection<Integer> collection = new ArrayList<>();
        for (int i = 1; i <= 6; i++) {
            collection.add(i);
        }

        Iterator<Integer> iterator = collection.iterator();//遍历
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}
迭代器的删除方法
package cn.cdw.demo;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * @author DW-CHEN
 * 迭代器的删除方法
 */

public class Demo47 {
    public static void main(String[] args) {
        Collection<Integer> collection = new ArrayList<>();

        collection.add(1);
        collection.add(2);
        collection.add(2);
        collection.add(3);

        Iterator<Integer> iterator = collection.iterator();
        while (iterator.hasNext()) {
            if (2 == iterator.next()) {//日过有2这个元素,则删除
                iterator.remove();
            }
        }
            System.out.println(collection);
    }
}
增强for循环

简化了数组和Collection集合的遍历

  1. 它是JDK5之后出现的,其内部原理是一个Iterator迭代器
  2. 实现Iterator接口的类才可以使用迭代器和增强for
package cn.cdw.demo;

import java.util.ArrayList;
import java.util.Collection;

/**
 * @author DW-CHEN
 * 增强for循环
 */
public class Demo48 {
    public static void main(String[] args) {
        Collection<Character> collection = new ArrayList<>();

        for (int i = 0; i < 26; i++) {
            collection.add((char) ('a' + i));//添加a-z到集合
        }

        for (Character character : collection) {//遍历
            System.out.println(character);
        }
    }
}
  • 定义学生对象存储到集合中并遍历
package cn.cdw.demo;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Scanner;

/**
 * @author DW-CHEN
 * 定义学生对象存储到集合中并遍历
 */
public class Demo49 {
    public static void main(String[] args) {
        Collection<Student3> collection = new ArrayList<>();
        Scanner scanner = new Scanner(System.in);

        for (int i = 0; i < 2; i++) {//键盘录入2个学生对象数据存储到集合
            System.out.print("请输入第"+ (i+1)+"个学生的姓名:");
            String name = scanner.next();
            System.out.print("请输入第"+ (i+1)+"个学生的年龄:");
            Integer age = scanner.nextInt();

            Student3 student3 = new Student3(name, age);
            collection.add(student3);
        }

        System.out.println("=========================迭代器方式遍历==============================");
        Iterator<Student3> iterator = collection.iterator();
        while (iterator.hasNext()) {
            Student3 student3 = iterator.next();
            System.out.println("姓名:" + student3.getName() + "  年龄:" + student3.getAge());
        }

        System.out.println("=========================增强for方式遍历==============================");
        for (Student3 student3 : collection) {
            System.out.println("姓名:" + student3.getName() + "  年龄:" + student3.getAge());
        }
    }
}

class Student3{
    private String name;
    private Integer age;

    public Student3(){

    }

    public Student3(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}
三种循环的使用场景
  1. 如果需要操作索引,使用普通的for循环
  2. 如果遍历的过程中需要删除元素,使用迭代器
  3. 如果仅仅是想遍历,使用增强for循环

List

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

List集合特点

  1. 有序,存储和取出的元素顺序一致
  2. 有索引,可以通过索引操作元素
  3. 可重复,存储的元素可以重复
List集合特有的方法
方法名说明
void add(int index,E element)在此集合中的指定位置插入指定的元素
E remove(int index)删除指定索引处的元素,返回被删除的元素
E set(int index,E element)修改指定索引处的元素,返回被修改的元素
E get(int index)返回指定索引处的元素
package cn.cdw.demo;

import java.util.ArrayList;
import java.util.List;

/**
 * @author DW-CHEN
 * List集合
 */
public class Demo50 {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();

        for (int i = 1; i <= 6; i++) {
            list.add(i);
        }
        System.out.println("添加了6个元素到集合中后的集合:" + list);

        list.add(0, 00);
        System.out.println("在指定0索引处添加一个00元素后的集合:" + list);

        System.out.println("删除指定0索引的的元素:"+list.remove(0) + "  " + list);

        System.out.println("设置指定的第5个索引的的元素修改为66:"+list.set(5, 66) + "  " + list);

        System.out.println("获得指定的第5个索引处的元素:"+list.get(5));

    }
}
数据结构

数据结构是计算存储,组织数据的方式。指相互之间存在一种或多种特定关系的数据元素和集合,选择合适的数据结构可以给我们带来更高的运行或者存储效率

  1. 栈:先进后出
  2. 队列:先进先出
  3. 数组:查询块,增删慢
  4. 链表:查询慢,增删块
List集合常用实现类
  • ArrayList:底层数据结构是数组,查询快,增删慢
  • LinkedList:底层数据结构是列表,查询慢,增删快

ArrayList

底层的数据结构是数组,查询快,增删慢

package cn.cdw.demo;

import java.util.ArrayList;

/**
 * @author DW-CHEN
 * ArrayList
 */
public class Demo51 {
    public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<>();

        for (int i = 1; i <= 6; i++) {
            arrayList.add(i);
        }

        System.out.println(arrayList);
    }
}

LinkedList

底层数据结构是列表,查询慢,增删快

Linked集合的特有功能
方法名说明
public void addFirst(E e)在该列表开头插入指定的元素
public void addLast(E e)将指定的元素追加到此列表的末尾
public E getFirst()返回此列表中的第一个元素
public E getLast()返回此列表中的最后一个元素
public E removeFirst()从此列表中删除并返回第一个元素
public E removeLast()从此列表中删除并返回最后一个元素
package cn.cdw.demo;

import java.util.LinkedList;

/**
 * @author DW-CHEN
 * LinkedList
 */
public class Demo52 {
    public static void main(String[] args) {
        LinkedList<Integer> linkedList = new LinkedList<>();
        for (int i = 1; i <= 6; i++) {
            linkedList.add(i);
        }
        System.out.println(linkedList);
    }
}

泛型

JDK5中引入的特征,它提供了编译时类型安全检测机制

  • 泛型的好处
  1. 把运行时期的问题提前到编译时期
  2. 避免了强制类型转换
  • 泛型可以使用的地方
    1.类后面:修饰符 class 类名<类型> { }
    2.方法声明上: 修饰符<类型> 返回值类型 方法名(类名 变量名){ }
    3.接口后面 : 修饰符 interface 接口名<类型> { }

  • 类型的通配符<?>

  1. 类型通配符上限:<? extends 类型>
  2. 类型通配符下限:<? super 类型>

Set

无须
无索引
不重复

Set集合的特点
  1. 可以去除重复元素
  2. 存取顺序不一致
  3. 没有带索引的方法,所以不能使用普通for循环遍历,也不能通过索引来获取/删除Set集合的元素
package cn.cdw.demo;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * @author DW-CHEN
 * Set
 */
public class Demo53 {
    public static void main(String[] args) {
        Set<Integer> set = new HashSet<>();

        for (int i = 1; i <= 6; i++) {
            set.add(i);
        }
        System.out.println(set);

        for (int i = 1; i <= 6; i++) {//添加重复元素
            set.add(i);
        }
        System.out.println(set);

        for (Integer s : set) {//增强for遍历
            System.out.println(s);
        }
        System.out.println("======================================================================");

        Iterator<Integer> iterator = set.iterator();//迭代器遍历
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}
TreeSet

底层数据结构:红黑树,必须给定排序规则

TreeSet集合特点
  1. 不包含重复元素的集合
  2. 没有带索引的方法
  3. 可以将元素按照规则进行排序
自然排序Comparable
  1. 使用空参构造创建TreeSet集合
  2. 自定义的学生类对象实现Comparable接口
  3. 重写compareTo方法

在TreeSet集合中存储学生对象,根据学生对象年龄排序,如果年龄相同则按姓名字母排序

package cn.cdw.demo;

import java.util.TreeSet;

/**
 * @author DW-CHEN
 * 排序之Comparable
 * 在TreeSet集合中存储学生对象,根据学生对象年龄排序,如果年龄相同则按姓名字母排序
 */
public class Demo54 {
    public static void main(String[] args) {
        TreeSet<Student4> treeSet = new TreeSet<>();

        Student4 s1 = new Student4("c", 12);
        Student4 s2 = new Student4("b", 12);
        Student4 s3 = new Student4("a", 15);

        treeSet.add(s1);
        treeSet.add(s2);
        treeSet.add(s3);

        for (Student4 student4 : treeSet) {//遍历
            System.out.println("姓名:" + student4.getName() + "  年龄:" + student4.getAge());
        }
    }
}

class Student4 implements Comparable<Student4>{
    private String name;
    private Integer age;

    public Student4(){

    }

    public Student4(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public int compareTo(Student4 o) {
        int result = this.age - o.age;
        result = result == 0 ? this.name.compareTo(o.name) : result;//如果年龄相同根据姓名字母排序

        return result;
    }
}
比较器排序Comparator
  1. TreeSet的带参数构造方法使用的时比较强排序对元素进行排序的
  2. 比较强排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法
  3. 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件写

在TreeSet集合中存储学生对象,根据学生对象年龄排序,如果年龄相同则按姓名字母排序

package cn.cdw.demo;

import java.util.TreeSet;

/**
 * @author DW-CHEN
 * 排序之comparator
 * 在TreeSet集合中存储学生对象,根据学生对象年龄排序,如果年龄相同则按姓名字母排序
 */
public class Demo55 {
    public static void main(String[] args) {

       /* Comparator<Student5> comparator = new Comparator<Student5>() {//方式一:外部定义比较器
            @Override
            public int compare(Student5 o1, Student5 o2) {
                int result = o1.getAge() - o2.getAge();
                result = result == 0 ? o1.getName().compareTo(o2.getName()) : result;
                return result;
            }
        };

        TreeSet<Student5> treeSet = new TreeSet<>(comparator);*/

        /*TreeSet<Student5> treeSet = new TreeSet<>(new Comparator<Student5>() {//方式二:使用匿名内部类直接在参数中定义比较器
            @Override
            public int compare(Student5 o1, Student5 o2) {
                int result = o1.getAge() - o2.getAge();
                result = result == 0 ? o1.getName().compareTo(o2.getName()) : result;
                return result;
            }
        });*/

        TreeSet<Student5> treeSet = new TreeSet<>((Student5 o1, Student5 o2) -> {//方式三:使用lambda表达式直接在参数中定义比较器
            int result = o1.getAge() - o2.getAge();
            result = result == 0 ? o1.getName().compareTo(o2.getName()) : result;
            return result;
        });

        Student5 s1 = new Student5("c", 12);
        Student5 s2 = new Student5("b", 12);
        Student5 s3 = new Student5("a", 15);

        treeSet.add(s1);
        treeSet.add(s2);
        treeSet.add(s3);

        for (Student5 student5 : treeSet) {//遍历
            System.out.println("姓名:" + student5.getName() + "  年龄:" + student5.getAge());
        }
    }
}

class Student5 {
    private String name;
    private Integer age;

    public Student5() {

    }

    public Student5(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

}
两种比较方式结论
  • 自然排序:自定义类实现Comparable接口,重写compareTo方法,根据返回值进行排序
  • 比较器排序:创建TreeSet对象的时候传递Comparator的实现类对象,重写compare方法,根据返回值进行排序
  • 在使用的时候,默认使用自然排序,当自然排序不满足现在需求时,使用比较器排序

两种方式中,关于返回值的规则

  • 如果返回值为负数,表示当前存入的元素时较小值,存左边
  • 如果返回值为0,表示当前存入的元素跟集合中的元素重复了,不存
  • 如果返回值为正数,表示当前存入的元素时较大值,存右边

对TreeSet集合中不同长度的字符串进行从段到长进行排序,如果长度相同则根据字母自然排序

package cn.cdw.demo;

import java.util.TreeSet;

/**
 * @author DW-CHEN
 * 对TreeSet集合中不同长度的字符串进行从段到长进行排序,如果长度相同则根据字母自然排序
 */
public class Demo56 {
    public static void main(String[] args) {
        TreeSet<String> treeSet = new TreeSet<>((String s1,String s2) -> {
            int result = s1.length() - s2.length();
            result = result == 0 ? s1.compareTo(s2) : result;
            return result;
        });

        String s1 = "da";
        String s2 = "daed";
        String s3 = "dda";
        String s4 = "daad";

        treeSet.add(s1);
        treeSet.add(s2);
        treeSet.add(s3);
        treeSet.add(s4);

        for (String s : treeSet) {//b遍历
            System.out.println(s);
        }
    }
}
HashSet
  • 底层数据结构:哈希表,重写hashCode和equals方法
    JDK8之前,底层采用数组 + 链表实现
    JDK8之后,底层进行了优化,由数组 + 链表 + 红黑树实现
HashSet集合特点
  • 底层数据结构时哈希表
  • 存取顺序不一致
  • 没有带索引的方法,索引不能使用普通for循环遍历
  • 元素不重复
package cn.cdw.demo;

import java.util.HashSet;

/**
 * @author DW-CHEN
 * HashSet
 */
public class Demo57 {
    public static void main(String[] args) {
        HashSet<Integer> hashSet = new HashSet<>();

        for (int i = 1; i <= 6; i++) {
            hashSet.add(i);
        }

        System.out.println(hashSet);

        for (Integer i : hashSet) {
            System.out.println(i);
        }
    }
}
哈希值

是JDK根据对象的地址或者属性值,算出来的int类型的整数

  • 获取对象的哈希值:public int hashCode();
对象的哈希值特点
  • 如果没有重写hashCode方法,那么根据对象的地址值算出哈希值。同一个对象多次调用hashCode()方法返回的哈希值是相同的,不同的对象的哈希值是不一样的
  • 如果重写了hashCode方法,一般都是通过对象的属性值计算出哈希值。如果不同对象的属性值一样,那么计算出来的哈希值也是一样的

在HashSet 集合中存储学生对象,如果姓名和年龄都相同,那么不存储(需重写hashCode方法)

package cn.cdw.demo;

import java.util.HashSet;

/**
 * @author DW-CHEN
 * 在HashSet 集合中存储学生对象,如果姓名和年龄都相同,那么不存储(需重写hashCode方法)
 */
public class Demo58 {
    public static void main(String[] args) {
        HashSet<Student6> hashSet = new HashSet<>();

        Student6 s1 = new Student6("小明", 12);
        Student6 s2 = new Student6("小明", 12);
        Student6 s3 = new Student6("小小", 21);

        hashSet.add(s1);
        hashSet.add(s2);
        hashSet.add(s3);

        for (Student6 student6 : hashSet) {
            System.out.println("姓名:" + student6.getName() + "  年龄:" + student6.getAge());
        }
    }
}

class Student6 {
    private String name;
    private Integer age;

    public Student6() {

    }

    public Student6(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Student6 student6 = (Student6) o;

        if (!name.equals(student6.name)) return false;
        return age.equals(student6.age);
    }

    @Override
    public int hashCode() {
        int result = name.hashCode();
        result = 31 * result + age.hashCode();
        return result;
    }
}

Map

  • Interface Map<K,V> -------------K:键的数据类型,V:值的数据类型
  • 键不能重复,值可以重复
  • 键和值一一对应的,每一个键只能找到自己对应的值
  • (键 + 值)这个整体称为 ”键值对" 或者 “键值对对象”,在Java中叫做 “entry对象”
package cn.cdw.demo;

import java.util.HashMap;
import java.util.Map;

/**
 * @author DW-CHEN
 * 双列集合Map
 */
public class Demo59 {
    public static void main(String[] args) {
        Map<String, Object> map = new HashMap<>();

        for (int i = 1; i <= 6; i++) {
            map.put(("s") + i, i);
        }
        System.out.println(map);
    }
}
Map集合的基本功能
方法名说明
V put(K key,V value)添加元素
V remove(Object key)根据键删除键值对元素
void clear()清空所有的键值对元素
boolean containsKey(Object key)判断集合中是否包含指定的键
boolean containsValue(Object value)判断集合中是否包含指定的值
boolean inEmpty()判断集合是否为空
int size()集合的长度,就是集合中键值对的个数
package cn.cdw.demo;

import java.util.HashMap;
import java.util.Map;

/**
 * @author DW-CHEN
 * Map
 */
public class Demo60 {
    public static void main(String[] args) {
        Map<String, Object> map = new HashMap<>();

        for (int i = 1; i <= 6; i++) {
            map.put("s" + i, i);
        }
        System.out.println("在map集合中添加数据后的map:"+map);

        System.out.println("map集合中根据指定的键删除键为s1的数据进行删除后的map:" + map.remove("s1") + "  " + map);

        System.out.println("是否包含指定的键s1的键在map中:"+map.containsKey("s1")+"  "+map);

        System.out.println("是否包含指定的键2的值在map中:" + map.containsValue(2) + "  " + map);

        System.out.println("map是否为空:" + map.isEmpty() + "  " + map);

        System.out.println("map的长度: "+map.size() + "  "+map);

        map.clear();
        System.out.println("清空后的map:"+map);

    }
}
Map集合的获取功能(遍历)
方法名说明
Set< K > keySet获取所有的键集合
V get(Object key)根据键获取值
Set<Map.Entry<K,V> >entrySet()获取所有键值对对象的集合
K getKey()获得键
V getValue()获得值
package cn.cdw.demo;

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

/**
 * @author DW-CHEN
 * 遍历map集合
 */
public class Demo61 {
    public static void main(String[] args) {
        Map<String, Object> map = new HashMap<>();

        for (int i = 1; i <= 6; i++) {
            map.put("s" + i, i);
        }

        Set<String> keySet = map.keySet();//方式一遍历
        for (String key : keySet) {
            System.out.println("key:" + key + "  value:" +map.get(key));
        }
        System.out.println("========================================================================");

        Set<Map.Entry<String, Object>> entries = map.entrySet();//方式二遍历
        for (Map.Entry<String, Object> entry : entries) {
            System.out.println("key:" + entry.getKey() + "  value:" + entry.getValue());
        }
    }
}
HashMap

HashMap的特点

  • HashMap是Map里面的一个实现类,直接使用Map里面的方法就可以了
  • HashMap和HashSet底层都是哈希表结构
  • 依赖hashCode方法和equals方法保证键的唯一
  • 如果键存储的是自定义对象,需要重写hashCode和equals方法保证键的唯一

HashMap中存储自定义学生对象,然后遍历

package cn.cdw.demo;

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

/**
 * @author DW-CHEN
 * HashMap中存储自定义学生对象,然后遍历
 */
public class Demo62 {
    public static void main(String[] args) {
        Map<String, Student7> map = new HashMap<>();

        Student7 s1 = new Student7("小明", 12);
        Student7 s2 = new Student7("小明", 12);
        Student7 s3 = new Student7("小李", 21);

        map.put("s1", s1);
        map.put("s2", s2);
        map.put("s3", s3);

        Set<String> keySet = map.keySet();//方式一遍历,keySet
        for (String key : keySet) {
            System.out.println(key + "----------" + "姓名:" + map.get(key).getName() + " 年龄:" + map.get(key).getAge());
        }
        System.out.println("===========================================================================================");

        Set<Map.Entry<String, Student7>> entries = map.entrySet();//方式二遍历,entrySet
        for (Map.Entry<String, Student7> entry : entries) {
            System.out.println(entry.getKey() + "----------" + "姓名:" + entry.getValue().getName() + " 年龄:" + entry.getValue().getAge());
        }
        System.out.println("===========================================================================================");

        map.forEach((String key,Student7 value) -> {//方式三遍历,lambda表达式
            System.out.println(key + "----------"+ "姓名:"+value.getName() + " 年龄:"+value.getAge());
        });
    }
}

class Student7 {
    private String name;
    private Integer age;

    public Student7() {

    }

    public Student7(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}
TreeMap

TreeMap的特点

  • TreeMap是Map里面的一个实现类,直接使用Map里面的方法就可以了
  • TreeMap和TreeSet底层都是红黑树结构
  • 依赖自然排序或者比较强排序,对键进行排序
  • 如果键存储的是自定义对象,需要实现Comparable接口或者创建TreeMap对象的时候给出比较器排序规则

在TreeMap集合中存储自定义学生对象,遍历根据年龄排序,如果年龄相同则根据姓名字母排序

package cn.cdw.demo;

import java.util.TreeMap;

/**
 * @author DW-CHEN
 * 在TreeMap集合中存储自定义学生对象,遍历根据年龄排序,如果年龄相同则根据姓名字母排序
 *
 * 排序:Comparable/Comparator
 */
public class Demo63 {
    public static void main(String[] args) {
        TreeMap<Student8,String> treeMap = new TreeMap<>();

        Student8 s1 = new Student8("a", 12);
        Student8 s2 = new Student8("c", 21);
        Student8 s3 = new Student8("ab", 12);

        treeMap.put(s1, "深圳");
        treeMap.put(s2, "北京");
        treeMap.put(s3, "上海");

        treeMap.forEach((Student8 key,String value)->{
            System.out.println(key+"----------"+value);
        });

    }
}

class Student8 implements Comparable<Student8> {
    private String name;
    private Integer age;

    public Student8() {

    }

    public Student8(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student8{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public int compareTo(Student8 o) {
        int result = this.age - age;
        result = result == 0 ? this.name.compareTo(o.name) : result;
        return result;
    }
}

可变参数

就是形参的个数是可以变化的
格式:修饰符 返回值类型 方法名(数据类型… 变量名){ }

注意

  • 这里的变量其实就是一个数组
  • 如果这个方法有多个参数,包含可变参数,可变参数要放到最后

使用可变参数计算n个数的和

package cn.cdw.demo;

/**
 * @author DW-CHEN
 * 使用可变参数计算n个数的和
 */
public class Demo64 {
    public static void main(String[] args) {
        method(1,2,3,4,5);
    }

    public static void method(int... ints) {
        int sum =0;
        for (int i : ints) {
            sum +=i;
        }
        System.out.println("计算的总和为:"+sum);
    }
}

Stream流

将集合中开头为 将开头为 “小” 长度为3的存储到另一个集合中并遍历

package cn.cdw.demo;

import java.util.ArrayList;

/**
 * @author DW-CHEN
 * Stream流
 *
 * 将集合中开头为 将开头为 “小” 长度为3的存储到另一个集合中并遍历
 */
public class Demo65 {
    public static void main(String[] args) {
        ArrayList<String> arrayList = new ArrayList<>();
        ArrayList<String> arrayList1 = new ArrayList<>();
        ArrayList<String> arrayList2 = new ArrayList<>();

        arrayList.add("小明");
        arrayList.add("小小名");
        arrayList.add("小小红");
        arrayList.add("张三");

        System.out.println("======================常规方式========================");
        for (String s : arrayList) {
            if (s.startsWith("小")) {
                arrayList1.add(s);
            }
        }

        for (String s : arrayList1) {
            if (s.length() == 3) {
                arrayList2.add(s);
            }
        }

        for (String s : arrayList2) {
            System.out.println(s);
        }
        System.out.println();

        System.out.println("======================Stream流方式========================");
        arrayList.stream().filter(s -> s.startsWith("小")).filter(s -> s.length() == 3).forEach(s -> {
            System.out.println(s);
        });

    }
}

Stream流的三类方法

  • 获取Stream流:创建一个流水线,并把数据放到流水线上准备进行操作
  • 中间方法:流水线上的操作,一次操作完毕之后,还可以继续进行其他的操作
  • 终结方法:一个Stream只能有一个终结方法,是流水线上的最后一个操作
Stream流的获取方法
  • 单列集合:default Stream< E > stream()
  • 双列集合:间接生成流,先通过keySet或者entrySet获取一个Set集合,在获取Stream流
  • 数组:Arrays中的静态方法stream生成流
  • 同种数据类型的多个数据:Stream.of(T… values)生成流
package cn.cdw.demo;

import java.util.*;
import java.util.stream.Stream;

/**
 * @author DW-CHEN
 * Stream流的获取方法
 */
public class Demo66 {
    public static void main(String[] args) {
        System.out.println("======================单列集合获取Stream流=============================");
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("aa");
        arrayList.add("cc");
        arrayList.add("dd");
        arrayList.stream().forEach(s -> { //单列集合获取Stream流
            System.out.println(s);
        });

        System.out.println();
        System.out.println("======================双列集合获取Stream流=============================");
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("s1","aa");
        hashMap.put("s2","cc");
        hashMap.put("s3","dd");

        hashMap.keySet().stream().forEach(s -> {
            System.out.println(s + "=" + hashMap.get(s));
        });
        System.out.println("==============================");
        hashMap.entrySet().stream().forEach(s -> {
            System.out.println(s);
        });

        System.out.println();
        System.out.println("======================数组获取Stream流=============================");
        int[] arr = {1,2,3,4,5,6};
        Arrays.stream(arr).forEach(s -> {
            System.out.println(s);
        });

        System.out.println();
        System.out.println("======================同种数据类型的多个数据获取Stream流=============================");
        Stream.of(1, 3, 5, 6, 7).forEach(s -> {
            System.out.println(s);
        });

    }
}
Stream流的常见中间操作方法
  • Stream< T >filter(Predicate predicate):对流中的数据进行过滤
    Predicate接口中的方法:boolean test(T t)对给定的参数进行判断,返回一个布尔值
package cn.cdw.demo;

import java.util.ArrayList;
import java.util.function.Predicate;

/**
 * @author DW-CHEN
 * Stream流的常见中间操作方法filter
 *
 * 将集合中开头为“小”的查询遍历出来
 */
public class Demo67 {
    public static void main(String[] args) {
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("小明");
        arrayList.add("小里");
        arrayList.add("张张");

        System.out.println();
        System.out.println("=====================方式一:使用匿名内部类============================");
        arrayList.stream().filter(new Predicate<String>() {//方式一:使用匿名内部类
            @Override
            public boolean test(String s) {
                boolean b =s.startsWith("小");
                return b;
            }
        }).forEach(s -> {
            System.out.println(s);
        });

        System.out.println();
        System.out.println("=====================方式二:Lambda表达式============================");
        arrayList.stream().filter((String s) -> {
            boolean b = s.startsWith("小");
            return  b;
        }).forEach(s -> {
            System.out.println(s);
        });

        System.out.println();
        System.out.println("=====================方式三:Lambda表达式简化============================");
        arrayList.stream().filter(s -> s.startsWith("小")).forEach(s -> {
            System.out.println(s);
        });
    }
}
方法名说明
Stream< T > limit(long maxSize)截取指定参数个数的数据
Stream< T > skip(long n)跳过指定参数个数的数据
static< T > Stream< T > concat(Stream a,Stream b)合并a和b两个流为一个流
Stream< T > distinct()去除流中重复的元素,(依赖hashCode和equals方法)
package cn.cdw.demo;

import java.util.ArrayList;
import java.util.stream.Stream;

/**
 * @author DW-CHEN
 * Stream流常见的中间操作方法
 */
public class Demo68 {
    public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<>();
        ArrayList<Integer> arrayList1 = new ArrayList<>();

        for (int i = 1; i <= 6; i++) {
            arrayList.add(i);
        }

        for (int i = 7; i <= 10; i++) {
            arrayList1.add(i);
        }

        arrayList.stream().limit(2).forEach(s -> { //截取集合前面两个数据
            System.out.println(+s);
        });

        System.out.println();
        System.out.println("===========================================================");
        arrayList.stream().skip(2).forEach(s -> {//跳过集合前面两个参数
            System.out.println(s);
        });

        System.out.println();
        System.out.println("===========================================================");
        Stream<Integer> concat = Stream.concat(arrayList.stream(), arrayList1.stream());//合并两个流为一个流
        concat.forEach(s -> {
            System.out.println(s);
        });

        System.out.println();
        System.out.println("===========================================================");
        arrayList.add(5);
        arrayList.add(6);
        System.out.println("没有去重复元素前:"+arrayList);
        System.out.println("去除重复元素之后:" );
        arrayList.stream().distinct().forEach(s -> {
            System.out.println(s);
        });
    }
}
Stream流常见终结操作方法
  • void forEach(Consumer action):对此流的每个元素指向操作
    Consumer接口中的方法------------void accept(T t):对给定的参数执行此操作

  • long count() :返回此流中的元素个数

package cn.cdw.demo;

import java.util.ArrayList;
import java.util.function.Consumer;

/**
 * @author DW-CHEN
 * Stream常见的终结操作方法
 */
public class Demo69 {
    public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<>();

        for (int i = 1; i <= 6; i++) {
            arrayList.add(i);
        }

        System.out.println();
        System.out.println("=====================方式一:使用匿名内部类============================");
        arrayList.stream().forEach(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) {
                System.out.println(integer);
            }
        });

        System.out.println();
        System.out.println("=====================方式二:Lambda表达式============================");
        arrayList.stream().forEach((Integer i) -> {
            System.out.println(i);
        });

        System.out.println();
        System.out.println("=====================方式三:Lambda表达式简化============================");
        arrayList.stream().forEach(i -> {
            System.out.println(i);
        });

        System.out.println();
        System.out.println("=====================返回此流中元素个数============================");
        Long count = arrayList.stream().count();
        System.out.println(count);
    }
}

集合中存储1到10,使用流输出偶数

package cn.cdw.demo;

import java.util.ArrayList;

/**
 * @author DW-CHEN
 * 集合中存储1到10,使用流输出偶数
 */
public class Demo70 {
    public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<>();

        for (int i = 1; i <= 10; i++) {
            arrayList.add(i);
        }

        arrayList.stream().filter(s -> s %2 == 0).forEach(s -> {
            System.out.println(s);
        });
    }
}
Stream流的收集操作
  • Stream流的收集方法: R collect(Collector collector)

工具类Collectors提供了具体的收集方式

方法名说明
public static < T > Collector toList()把元素收集到List集合中
public static < T > Collector toSet()把元素集合收集到Set集合中
public static Collector toMap(Function keyMapper,Function valuesMapper)把元素收集到Map集合中

Stream流的收集操作(单列集合)

package cn.cdw.demo;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author DW-CHEN
 * Stream流的收集操作(单列集合)
 */
public class Demo71 {
    public static void main(String[] args) {
        ArrayList<Integer> arrayList = new ArrayList<>();

        for (int i = 1; i <= 10; i++) {
            arrayList.add(i);
        }

        System.out.println("================将Stream流中的偶数存储到list集合====================");
        List<Integer> list = arrayList.stream().filter(i -> i % 2 == 0).collect(Collectors.toList());
        System.out.println(list);

        System.out.println();
        System.out.println("================将Stream流中的奇数存储到Set集合====================");
        arrayList.add(1);
        arrayList.add(3);
        System.out.println("没有去除重复元素:" + arrayList);

        Set<Integer> set = arrayList.stream().filter(i -> i % 2 != 0).collect(Collectors.toSet());
        System.out.println(set);
    }
}

Stream流的收集操作(双列集合)

package cn.cdw.demo;

import java.util.ArrayList;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author DW-CHEN
 * Stream流的收集操作(双列集合)
 *
 * 将姓名和年龄存储到一个集合中,姓名和年龄使用逗哈隔开,将年龄大于23岁的保存到map集合中
 */
public class Demo72 {
    public static void main(String[] args) {
        ArrayList<String> arrayList = new ArrayList<>();

        arrayList.add("小明,21");
        arrayList.add("小李,25");
        arrayList.add("小小,26");

        Map<String, Integer> map = arrayList.stream().filter(s -> {
            String[] sp = s.split(",");
            Integer age = Integer.valueOf(sp[1]);
            return age > 23; //过滤条件
        }).collect(Collectors.toMap(
                s -> s.split(",")[0],//key
                s -> Integer.valueOf(s.split(",")[1])//value
        ));
        System.out.println(map);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值