Java中lambda表达式的使用(二)

简介: Java中lambda表达式的使用(二)

Java中lambda表达式的使用(一)+https://developer.aliyun.com/article/1413557

4.lambda表达式中的变量捕获

 lambda表达式可以看作对匿名内部类进行的语法上的精简,同时也可以进行变量的捕获

@FunctionalInterface
interface DemoTest {
    void func();
}

当使用被修改过的变量 -->依然报错

尽量使用被final修饰的变量

引用类变量

@FunctionalInterface
interface DemoTest {
    void func();
}
public class Demo10 {
    // 使用类变量  可以直接访问
    public static int a = 10;
    public static void main(String[] args) {
        // lambda表达式
        DemoTest demoTest = () -> {
            System.out.println(a);
        };
    }

对于类变量来说,在lambda表达式中可以直接引用,因为类变量是属于类的,是所有对象公用的,它本身就有"静态"的属性

五.在优先级队列中的使用

 优先级队列中往往涉及到比较,我们在实例化优先级队列的时候往往要传递一个比较器,规定比较的对象

// 使用匿名内部类实现Comparator接口
        PriorityQueue<Integer> priorityQueue = new PriorityQueue(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return  o2 - o1;
            }
        });

其实也能看出,Comparator方法应该是一个函数式接口,它属于"多个参数,有返回值"的类型(对应于上面的最后一种情况),此处就可以使用lambda表达式进行语法上的精简

// 使用lambda表达式实现优先级队列中的比较
        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>((o1,o2) ->{return o1-o2;});

Comparator的源码 -->多个参数,有返回值的接口

六.创建线程

创建线程的方式有很多种,可以采用匿名内部类,lambda表达式

1.匿名内部类创建线程

// 创建线程 ->使用匿名内部类
        Thread thread1 = new Thread() {
            @Override
            public void run() {
                System.out.println("hello thread");
            }
        };
        // 这种方式可以降低耦合性(推荐)
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello thread2");
            }
        });

为什么可以使用匿名内部类创建一个线程呢?主要是因为Thread类实现了Runnable接口,这个接口是一个函数式接口,只有一个抽象方法run()

2.使用lambda表达式

 既然Thread可以通过匿名内部类方式创建线程,同时就可以使用lambda表达式来简化创建

// 方式1
        Thread thread1 = new Thread(() ->{
            System.out.println("hello thread1");
        });
        thread1.run();// 输出hello thread1
        //方式2  利用lambda表达式实例化一个runnable接口  降低耦合性
        Runnable runnable = () -> System.out.println("hello thread2");
        Thread thread2 = new Thread(runnable);
        thread2.run();// 输出hello thread2

七.lambda表达式在集合类中的使用(以后最常用的一种)

为了能够让Lambda和Java的集合类集更好的一起使用,集合当中,也新增了部分接口,以便与Lambda表达式对 接。

1.Collection接口

1.1forEach()

1.源码

forEach()在Iterable接口之下,源码如下:

default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

对传入的集合的每个元素执行action操作,进一步观察

可以观察到。forEach()方法接受了一个Comsumer类型的参数action,接着会对每一个action执行对应的操作。Consumer是一个函数式接口,属于"一个参数但无返回值"的类型,内部有一个抽象方法accept用于接受参数并执行特定的操作

2.使用匿名内部类实现
List<String> list = new ArrayList<>();
        list.add("hello");
        list.add("my");
        list.add("friends");
        list.add("!!!");
        list.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.print(s + " ");
            }
        });

3.使用lambda表达式
// lambda表达式
        list.forEach((s) -> System.out.print(s + " "));

1.2removeif()

 removeif()用于根据条件删除集合中的对应数据,如果有对应条件的数据,删除,并将标志位removed设置为true(注意:removeif不是只删除一个符合条件的数据,而是类似于removeAll一样的效果)

1.源码:
default boolean removeIf(Predicate<? super E> filter) {
        Objects.requireNonNull(filter);
        boolean removed = false;
        final Iterator<E> each = iterator();
        while (each.hasNext()) {
            if (filter.test(each.next())) {
                each.remove();
                removed = true;
            }
        }
        return removed;
    }
2.图解:

3.使用
List<String> list = new ArrayList<>();
        list.add("hello");
        list.add("my");
        list.add("friends");
        list.add("!!!");
        // 1.先打印原数据
        list.forEach((s) -> System.out.print(s + " "));
        // 2.删除长度 <= 3的字符串
        boolean flg = list.removeIf(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length() <= 3;
            }
        });
        System.out.println("");
        // 3.判断是否有删除操作
        System.out.println(flg);
        // 4.打印删除之后的数据
        list.forEach((s) -> System.out.print(s + " "));

打印结果:

2.List接口

2.1 sort

1.源码:
default void sort(Comparator<? super E> c) {
        Object[] a = this.toArray();
        Arrays.sort(a, (Comparator) c);
        ListIterator<E> i = this.listIterator();
        for (Object e : a) {
            i.next();
            i.set((E) e);
        }
    }
2.图解:

3.使用:
List<String> list = new ArrayList<>();
        list.add("hello");
        list.add("my");
        list.add("friends");
        list.add("!!!");
        // 使用匿名内部类
        list.sort(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);// 从小到大排序
            }
        });
        // 使用lambda表达式
        list.sort((o1,o2) -> {
            return o1.compareTo(o2);
        });
        list.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.print(s + " ");
            }
        });

打印结果:

2.2 reolaceAll

1.源码:
default void replaceAll(UnaryOperator<E> operator) {
        Objects.requireNonNull(operator);
        final ListIterator<E> li = this.listIterator();
        while (li.hasNext()) {
            li.set(operator.apply(li.next()));
        }
    }
2.图解:

3.使用:
List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        // 打印原数据
        System.out.println(list.toString());
        // 使用匿名内部类
        list.replaceAll(new UnaryOperator<Integer>() {
            @Override
            public Integer apply(Integer integer) {
                return integer*2;// 将所有的值都设置为原来的两倍
            }
        });
        // 使用lambda表达式
        list.replaceAll((x) ->{return x*2;});
        // 打印修改之后的数据
        System.out.println(list.toString());

打印数据:

3.Map接口

3.1 forEach

1.源码:
default void forEach(BiConsumer<? super K, ? super V> action) {
        Objects.requireNonNull(action);
        for (Map.Entry<K, V> entry : entrySet()) {
            K k;
            V v;
            try {
                k = entry.getKey();
                v = entry.getValue();
            } catch(IllegalStateException ise) {
                // this usually means the entry is no longer in the map.
                throw new ConcurrentModificationException(ise);
            }
            action.accept(k, v);
        }
    }
2.图解:

3.使用:
Map<String,Integer> map = new HashMap<>();
        map.put("zs",1);
        map.put("ls",2);
        map.put("ww",3);
        // 使用匿名内部类
        map.forEach(new BiConsumer<String, Integer>() {
            @Override
            public void accept(String s, Integer integer) {
                System.out.println("key:" + s + " val:" + integer);
            }
        });
        System.out.println("==============");
        // 使用lambda表达式
        map.forEach((key,val) ->{
            System.out.println("key:" + key + " val:" + val);
        });

打印结果:


目录
相关文章
|
21天前
|
数据采集 数据可视化 安全
最详细Java正则表达式详解
本文系统讲解Java正则表达式核心语法、API用法及性能优化技巧,结合代码示例与实战场景,助你掌握文本处理利器,提升开发效率。
448 120
|
2月前
|
安全 Java API
Java中的Lambda表达式:简洁与功能的结合
Java中的Lambda表达式:简洁与功能的结合
359 211
|
2月前
|
安全 Java
Java中的Switch表达式:更简洁的多路分支
Java中的Switch表达式:更简洁的多路分支
423 211
|
2月前
|
Java 编译器 API
Java Lambda表达式与函数式编程入门
Lambda表达式是Java 8引入的重要特性,简化了函数式编程的实现方式。它通过简洁的语法替代传统的匿名内部类,使代码更清晰、易读。本文深入讲解Lambda表达式的基本语法、函数式接口、方法引用等核心概念,并结合集合操作、线程处理、事件回调等实战案例,帮助开发者掌握现代Java编程技巧。同时,还解析了面试中高频出现的相关问题,助你深入理解其原理与应用场景。
|
3月前
|
自然语言处理 Java Apache
在Java中将String字符串转换为算术表达式并计算
具体的实现逻辑需要填写在 `Tokenizer`和 `ExpressionParser`类中,这里只提供了大概的框架。在实际实现时 `Tokenizer`应该提供分词逻辑,把输入的字符串转换成Token序列。而 `ExpressionParser`应当通过递归下降的方式依次解析
237 14
|
2月前
|
Java 编译器
Java 17 Switch表达式:更简洁、更强大的流程控制
Java 17 Switch表达式:更简洁、更强大的流程控制
|
3月前
|
设计模式 数据采集 Java
Java正则表达式的基础知识,进阶至熟练掌握。
通过大量的练习来熟悉它们的识别模式、如何设计模式来解决实际问题,才能够逐步达到熟练掌握。更多的是通过实践、编写代码和解决真实问题来完善技能。在这方面,没有快速的捷径,唯有刻意练习和长时间的代码实践。
80 0
|
4月前
|
SQL JSON 安全
Java 8 + 中 Lambda 表达式与 Stream API 的应用解析
摘要:本文介绍了Java 8+核心新特性,包括Lambda表达式与Stream API的集合操作(如过滤统计)、函数式接口的自定义实现、Optional类的空值安全处理、接口默认方法与静态方法的扩展能力,以及Java 9模块化系统的组件管理。每个特性均配有典型应用场景和代码示例,如使用Stream统计字符串长度、Optional处理Map取值、模块化项目的依赖声明等,帮助开发者掌握现代Java的高效编程范式。(150字)
79 1
|
6月前
|
缓存 监控 Java
深入解析java正则表达式
本文深入解析Java正则表达式的应用,从基础概念到实际开发技巧全面展开。正则表达式是一种强大的文本处理工具,广泛应用于格式验证、搜索替换等场景。Java通过`Pattern`和`Matcher`类支持正则表达式,`Pattern.compile()`方法将正则字符串编译为高效模式对象。文章详细介绍了核心类的功能、常用正则语法及实际案例(如邮箱和电话号码验证)。掌握这些内容,可显著提升文本处理能力,满足多种开发需求。
197 1

热门文章

最新文章