【黑马java基础】Lamda, 方法引用,集合{Collection(List, Set), Map},Stream流

文章目录

  • JDK8新特性:Lambda表达式
    • 认识Lambda表达式
    • Lambda表达式的省略规则
  • JDK8新特性:方法引用
    • 静态方法的引用
    • 实例方法的引用
    • 特定类型方法的引用
    • 构造器的应用
  • 集合
  • ➡️Collection单列集合体系
  • Collection的常用方法
  • Collection的遍历方法
    • 迭代器
    • 增强for循环
    • lambda表达式
    • 案例
  • List集合
    • List特点、特有方法
    • List的遍历方式
    • ArrayList集合的底层原理
      • ArrayList集合的底层原理
      • ArrayList集合适合的应用场景
    • LinkedList集合的底层原理
      • LinkedList集合的底层原理
      • **LinkedList**新增特有方法
      • **LinkedList**集合适合的应用场景
        • 场景一:可以用来设计队列
        • 场景二:可以用来设计栈
  • Set集合
    • Set集合的特点
    • HashSet集合的底层逻辑
        • 前导知识
          • 哈希值
          • 对象哈希值的特点
          • 哈希表
          • 数据结构(树)
        • HashSet集合底层原理
        • HashSet集合去重复的机制
    • LinkedHashSet集合的底层逻辑
    • TreeSet集合
  • ✅总结(场景选择)
  • 注意事项:集合的并发修改异常问题
  • Collection的其他相关知识
    • 可变参数
    • Collections工具类
    • 综合案例
  • ➡️Map集合
    • 概述
    • 常用方法
    • 遍历方法
      • 方法1:键找值
      • 方法2:键值对
      • 方法3:Lambda
    • 案例 Map集合-统计投票人数
    • HashMap
      • HashMap底层原理
    • LinkedHashMap
      • LinkedHashMap底层原理
    • TreeMap
    • 补充知识:集合的嵌套
  • Stream流
    • 认识Stream
      • Stream流的使用步骤
    • Stream的常用方法
      • 1、获取Stream流
      • 2、Stream流常见的中间方法
      • 3、Stream流常见的终结方法

JDK8新特性:Lambda表达式

认识Lambda表达式

  • Lambda表达式是DK8开始新增的一种语法形式,作用:用于简化匿名内部类的代码写法。

  • 格式:
    在这里插入图片描述

  • 注意:Lambda表达式并不能简化全部匿名内部类的写法,只能简化函数式接口(有且只有一个抽象方法的接口)的匿名内部类

package lambda;

public class LambdaTest1 {
    public static void main(String[] args) {
        Swimming s = new Swimming() {
            @Override
            public void swim() {
                System.out.println("学生游泳");
            }
        };
        s.swim();
    }
}

interface Swimming{
    void swim();
}

简化后:

package lambda;

public class LambdaTest1 {
    public static void main(String[] args) {
//        Swimming s = new Swimming() {
//            @Override
//            public void swim() {
//                System.out.println("学生游泳");
//            }
//        };
//        s.swim();

        //简化后:
        Swimming s = () -> {
            System.out.println("学生游泳");
        };
        s.swim();
    }
}

interface Swimming{
    void swim();
}
  • 将来我们见到的大部分函数式接口,上面都可能会有一个@FunctionalInterface的注解,有该注解的接口就必定是函数式接口。

在这里插入图片描述

Lambda表达式的省略规则

Lambda表达式的省略写法(进一步简化Lambda表达式的写法)

  • 参数类型可以省略不写。
  • 如果只有一个参数,参数类型可以省略,同时()也可以省略。
  • 如果Lambda表达式中的方法体代码只有一行代码,可以省略大括号不写,同时要省略分号!此时,如果这行代码是return语句,也必须去掉return不写。
Arrays.setAll(prices, (int value) ->{
    return prices[value] * 0.8;
});

//可以简化为:
Arrays.setAll(prices, (value) ->{
    return prices[value] * 0.8;
});

//接着简化:
Arrays.setAll(prices, value ->{
    return prices[value] * 0.8;
});

//接着简化:
Arrays.setAll(prices, value -> prices[value] * 0.8);

再或者:

Arrays.sort(students, new Comparator<Student>() {
    @Override
    public int compare(Student o1, Student o2){
        return Double.compare(o1.getHeight)
    }
});

//可以简化为:
Arrays.sort(students, (Student o1, Student o2) -> {
    return Double.compare(o1.getHeight(), o2.getHeight()); //升序
});

//接着简化:
Arrays.sort(students, (o1, o2) -> {
    return Double.compare(o1.getHeight(), o2.getHeight()); //升序
});

//接着简化:
Arrays.sort(students, (o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight()) );

用来简化函数式接口的匿名内部类

JDK8新特性:方法引用

用于进一步简化Lambda表达式的

方法引用的标志性符号 “ :: ”

静态方法的引用

  • 类名 :: 静态方法
  • 使用场景:如果某个Lambda表达式里只是调用一个静态方法,并且前后参数的形式一致,就可以使用静态方法引用

在这里插入图片描述

实例方法的引用

  • 对象名 :: 实例方法

  • 使用场景:如果某个Lambda表达式里只是调用一个实例方法,并且前后参数的形式一致,就可以使用实例方法引用

在这里插入图片描述

特定类型方法的引用

  • 类型 :: 方法

  • 使用场景:如果某个Lambda表达式里只是调用一个实例方法,并且前面参数列表中的第一个参数是作为方法的主调,后面的所有参数都是作为该实例方法入参的,则此时就可以使用特定类型的方法引用。

在这里插入图片描述

构造器的应用

  • 类名 :: new
  • 使用场景:如果某个Lambda表达式里只是在创建对象,并且前后参数的情况一致,就可以使用构造器引用

在这里插入图片描述

集合

集合是一种容器,用来装数据的,类似于数组,但集合的大小可变,开发中也非常常用

  • 集合的体系结构

在这里插入图片描述

在这里插入图片描述

集合分为:Collection单列集合,Map双列集合

➡️Collection单列集合体系

在这里插入图片描述

Collection集合特点:

  • List系列集合:添加的元素是有序(取时的顺序和拿时的顺序是一致的)、可重复(可以往集合中加一模一样的数据)、有索引。
    • ArrayList:有序、可重复、有索引
    • LinkedList:有序、可重复、有索引
  • Set系列集合:添加的元素是无序、不重复、无索引。
    • HashSet:无序、不重复、无索引
    • LinkedHashSet:有序、不重复、无索引
    • TreeSet:按照大小默认升序排序、不重复、无索引
package collection;

import java.util.ArrayList;
import java.util.HashSet;

public class CollectionTest1 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();  //List:有序 可重复 有索引
        list.add("java1");
        list.add("java2");
        list.add("java3");
        list.add("java4");
        list.add("java5");
        System.out.println(list);

        HashSet<String> set = new HashSet<>();   //Set: 无序 无重复 无索引
        set.add("java1");
        set.add("java2");
        set.add("java3");
        set.add("java2");
        set.add("java1");
        System.out.println(set);
    }
}

//Out:
[java1, java2, java3, java4, java5]
[java3, java2, java1]

集合的存储对象存的并不是元素本身,而是元素的地址,通过元素地址到栈里面获取元素

Collection的常用方法

Collection是单列集合的祖宗,它规定的方法(功能)是全部单列集合都会继承的。

  • Collection的常见方法:(单列集合都能用)

在这里插入图片描述

package collection;

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

public class CollectionTest2API {
    public static void main(String[] args) {
        Collection<String> c = new ArrayList<>();

        //1.public boolean add(E e):添加元素,添加成功返回true。
        c.add("java1");
        c.add("java1");
        c.add("java2");
        c.add("java2");
        c.add("java3");
        System.out.println(c);

        //2.public void clear():清空集合的元素。
//        c.clear();
//        System.out.println(c);

        //3.public boolean isEmpty():判断集合是否为空是空返回true,反之。
        System.out.println(c.isEmpty());

        //4.public int size():获取集合的大小。
        System.out.println(c.size());

        //5.public boolean contains(object obj):判断集合中是否包含某个元素。
        System.out.println(c.contains("java3"));
        System.out.println(c.contains("Java3"));   //精确匹配,所以是false

        //6.public boolean remove(E e):删除某个元素:如果有多个重复元素默认删除前面的第一个!
        System.out.println(c.remove("java1"));    //true
        System.out.println(c);

        //7.public Object[] toArray():把集合转换成数组
        Object[] arr = c.toArray();
        System.out.println(Arrays.toString(arr));

        String[] arr2 = c.toArray(new String[c.size()]);   //指定一个String类型的数组
        System.out.println(Arrays.toString(arr2));


        System.out.println("==============================");
        //把一个集合里的全部数据倒入到另一个集合中去
        Collection<String> c1 = new ArrayList<>();
        c1.add("java1");
        c1.add("java2");
        Collection<String> c2 = new ArrayList<>();
        c2.add("java3");
        c2.add("java4");
        c1.addAll(c2);  //就是把c2集合的全部数据倒入到c1集合中去
        System.out.println(c1);
        System.out.println(c2);  //不空,相当于拷贝


    }
}
//Out:
[java1, java1, java2, java2, java3]
false
5
true
false
true
[java1, java2, java2, java3]
[java1, java2, java2, java3]
[java1, java2, java2, java3]
==============================
[java1, java2, java3, java4]
[java3, java4]

Collection的遍历方法

迭代器

迭代器是用来遍历集合的专用方式(数组没有选代器),在java中选代器的代表是Iterator。

  • Collection集合获取迭代器的方法

在这里插入图片描述

  • Iterator迭代器中的常用方法

在这里插入图片描述

package collection;

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

public class CollectionDemo1 {
    public static void main(String[] args) {
        Collection<String> c = new ArrayList<>();
        c.add("aaa");
        c.add("sss");
        c.add("ddd");
        c.add("fff");
        System.out.println(c);

        // c = [aaa,sss,ddd,fff]
        //      it                  it的位置,it会把数据取出来,然后往后移动一位


        //使用迭代器遍历集合
        //1、从集合对象中获取迭代器对象
        Iterator<String> it = c.iterator();
//        System.out.println(it.next());
//        System.out.println(it.next());
//        System.out.println(it.next());
//        System.out.println(it.next());

//        System.out.println(it.next());  //出现异常:NoSuchElementException

        //2、我们应该使用循环结合迭代器遍历集合
        while (it.hasNext()){
            String ele = it.next();
            System.out.println(ele);
        }
    }
}
//Out:
[aaa, sss, ddd, fff]
aaa
sss
ddd
fff

增强for循环

在这里插入图片描述

  • 增强for可以用来遍历集合或者数组。
  • 增强for遍历集合,本质就是迭代器遍历集合的简化写法
package collection;

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

public class CollectionDemo2 {
    public static void main(String[] args) {
        Collection<String> c = new ArrayList<>();
        c.add("aaa");
        c.add("sss");
        c.add("ddd");
        c.add("fff");
        System.out.println(c);

        // c = [aaa,sss,ddd,fff]
        //      ele                    ele类似游标

        //使用增强for遍历集合或者数组
        //快捷键:c.for 然后回车,改变量名就行
        
        for (String ele : c){
            System.out.println(ele);
        }

        String[] names = {"11","22","33"};
        for (String name : names){
            System.out.println(name);
        }
    }
}

//Out:
[aaa, sss, ddd, fff]
aaa
sss
ddd
fff
11
22
33

lambda表达式

  • Lambda表达式遍历集合:

得益于JDK8开始的新技术Lambda表达式,提供了一种更简单、更直接的方式来遍历集合。

  • 需要使用Collection的如下方法来完成

在这里插入图片描述

在这里插入图片描述

package collection;

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

public class CollectionDemo3 {
    public static void main(String[] args) {
        Collection<String> c = new ArrayList<>();
        c.add("aaa");
        c.add("sss");
        c.add("ddd");
        c.add("fff");
        System.out.println(c);

        // c = [aaa,sss,ddd,fff]
        //       s
        
        c.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
    }
}
//Out:
[aaa, sss, ddd, fff]
aaa
sss
ddd
fff

可以用Lambda进行简化:

上一篇:C++类和对象(上)-5.构造函数


下一篇:【最新发布】生成式人工智能全球研究报告