Java8新特性/java

1.lambda表达式

区别于js的箭头函数,python、cpp的lambda表达式,java8的lambda是一个匿名函数,java8运行把函数作为参数传递进方法中。

  • 语法格式

    (parameters) -> expression 或
    (parameters...) ->{ statements; }
    
  • 实战

    1. 替代匿名内部类:java8之前如果想把方法传给函数(动态传递参数),那么需要匿名内部类

      • Runnable接口

        new Thread(new Runnable() {@Overridepublic void run() {System.out.println("The runable now is using!");}
        }).start();
        //用lambda
        new Thread(() -> System.out.println("It's a lambda function!")).start();
        
        特性静态传参动态传参
        参数数量固定:编译时确定可变:调用时可以变化
        方法定义参数数量和类型明确指定参数用 ... 形式声明,数量可变
        适用场景当参数数量固定时当参数数量不确定时
        调用方式需要按照方法定义传递确切的参数数量可以传递任意数量的同类型参数
        例子void method(int a, int b)void method(int... numbers)
      • Comparator 接口

        List<Integer> strings = Arrays.asList(1, 2, 3);Collections.sort(strings, new Comparator<Integer>) {
        @Overridepublic int compare (Integer o1, Integer o2) {return o1 - o2;}
        }Collections.sort(strings, (Integer o1, Integer o2) -> o1 - o2);
        
      • Listener接口

        JButton button = new JButton();
        button.addItemListener(new ItemListener() {
        @Override
        public void itemStateChanged(ItemEvent e) {e.getItem();
        }
        });
        //lambda
        button.addItemListener(e -> e.getItem());
        
      • 不难发现这些匿名内部类只重写了接口的一个方法,当然也只有一个方法要重写。这就是上文提到的函数式接口,也就是说只要方法的参数是函数式接口就可以用lambda表达式。

      • 自定义一个,java中的lambda就是减少实例化类这一步

        public class lambda {@FunctionalInterfacepublic interface LambdaInterface {void f();}//使用public static class LambdaClass {public static void forEg() {lambdaInterfaceDemo(() -> System.out.println("自定义函数式接口"));}//函数式接口参数static void lambdaInterfaceDemo(LambdaInterface i) {i.f();}}public static void main(String[] args) {LambdaClass.forEg();}
        }
        
    2. 集合迭代

      void lamndaFor() {List<String> strings = Arrays.asList("1", "2", "3");//传统foreachfor (String s : strings) {System.out.println(s);}//Lambda foreachstrings.forEach((s) -> System.out.println(s));//orstrings.forEach(System.out::println);//mapMap<Integer, String> map = new HashMap<>();map.forEach((k,v)->System.out.println(v));
      }
      
    3. 方法的引用

      • 静态方法的引用

        类名::静态方法

        package lambda;import java.util.Arrays;public class reference {public static void main(String[] args) {Student[] s = new Student[6];s[0] = new Student("张三", 18, "男", "北京");s[1] = new Student("李四", 19, "男", "上海");s[2] = new Student("王五", 20, "男", "广州");s[3] = new Student("赵六", 21, "男", "深圳");s[4] = new Student("孙七", 22, "男", "武汉");s[5] = new Student("周八", 23, "男", "西安");// lambda表达式,传入函数作为参数, 如果参数和调用的函数参数是一样的,才可以使用静态函数引用Arrays.sort(s, (o1, o2) -> o1.getAge() - o2.getAge());// 将类的静态方法作为引用,传送给函数式接口Arrays.sort(s, Student::compareByAge);}}
        
        package lambda;import lombok.AllArgsConstructor;
        import lombok.Data;
        import lombok.NoArgsConstructor;@Data
        @NoArgsConstructor
        @AllArgsConstructor
        public class Student {private String name;private int age;private String gender;private String address;public static int compareByAge(Student s1, Student s2){return s1.getAge() - s2.getAge();}
        }
        

        实例方法

        package lambda;import java.util.Arrays;public class reference {public static void main(String[] args) {Student[] s = new Student[6];s[0] = new Student("张三", 18, "男", "北京");s[1] = new Student("李四", 19, "男", "上海");s[2] = new Student("王五", 20, "男", "广州");s[3] = new Student("赵六", 21, "男", "深圳");s[4] = new Student("孙七", 22, "男", "武汉");s[5] = new Student("周八", 23, "男", "西安");// lambda表达式,传入函数作为参数, 如果参数和调用的函数参数是一样的,才可以使用静态函数引用Arrays.sort(s, (o1, o2) -> o1.getAge() - o2.getAge());Student s1 = new Student();// 将类的静态方法作为引用,传送给函数式接口Arrays.sort(s, s1::compareByAge);}}
        

        特定类的调用

        public void Demo3 {public static void main(String[] args) {String[] names = {"Tom", "Cat", "Jerry"};}// Arrays.sort(names); // 默认按照首字母的升序排序// 忽略字母大小写升序  如果是特定类型的实例方法,以及是对应类方法// Arrays.sort(names, (o1, o2) -> o1.compareToIgnore(o2));Arrays.sort(names, String::compareToIgnore);System.out.println(Array.toString(names));
        }
        

        构造方法

        在这里插入图片描述

        class Car{String name;String getName() {return this.name;}
        }interface CarFactory {Car getCar(String name);
        }
        // CarFactory cf = new CarFactory {
        //	@override
        //	public Car getCar(String name);
        //		return new Car(name);
        //}
        // CarFactory cf = name -> new Car(name);CarFactory cf = Car::new;
        Car c1 = cd.getCar();
        
  • 这些方法是可遇不可求的,一般都是重构写出来的代码。

2.Interface

背景:

  1. 传统接口的缺点:

    • 一旦接口需要修改或增加方法,实现该接口的所有类都需要进行改动**。例如,假设 Animal 接口增加了一个新的方法 eat(),那么所有已经实现 Animal 接口的类 (DogCat 等) 都必须去实现这个新增加的方法,否则代码会报错。

    • 这给代码的维护和扩展带来了很大的问题,尤其当你有很多实现类时,修改接口将变得代价非常高昂。

  2. default修饰的方法,是普通的实例方法,可以用this调用,也可以被子类继承、重写。

  3. static修饰的方法,使用上和一般的类静态方法一样。但它不能被子类继承、重写。

  4. private修饰的方法,接口内部类才可以使用

​ 例子:

public interface InterfaceNew {static void sm() {System.out.println("interface提供的方式实现");}static void sm2() {System.out.println("interface提供的方式实现");}default void def() {System.out.println("interface default方法");}default void def2() {System.out.println("interface default2方法");}//须要实现类重写void f();
}public interface InterfaceNew1 {default void def() {System.out.println("InterfaceNew1 default方法");}
}

因为两个接口没有继承关系,如果不重写def函数会编译出错

public class InterfaceNewImpl implements InterfaceNew , InterfaceNew1{public static void main(String[] args) {InterfaceNewImpl interfaceNew = new InterfaceNewImpl();interfaceNew.def();}@Overridepublic void def() {InterfaceNew1.super.def();}@Overridepublic void f() {}
}
  1. 抽象类和接口的区别
  • interface 和 class 的区别,好像是废话,主要有:

    • 接口多实现,类单继承
    • 接口的方法是 public abstract 修饰,变量是 public static final 修饰。 abstract class 可以用其他修饰符
  • interface 的方法是更像是一个扩展插件。而 abstract class 的方法是要继承的。

  1. functional interface接口
    • 也称SAM接口,既只有一个抽象方法的接口,在java8中有一个专门存放函数式接口的包java.util.function,该包下的所有接口都有@FunctionalInterface注解,提供函数式编程,提醒编译器,如果不是SAM接口解报错。

3.stream流

在这里插入图片描述

  • 实例

    package stream;import java.util.ArrayList;
    import java.util.List;
    import java.util.stream.Collectors;public class demo1 {public static void main(String[] args) {// 目标:认证stream流List<String> list = new ArrayList<>();list.add("hello");list.add("world");list.add("java");list.add("hello");list.add("hello");// 1.常规方法List<String> newList = new ArrayList<>();for (String name : list) {if (name.startsWith("h") && name.length() != 1) {newList.add(name);}}System.out.println(newList);// 2.stream流List<String> list2 =  list.stream().filter(name -> name.startsWith("h")).filter(name -> name.length() != 1).collect(Collectors.toList());System.out.println("------------------");System.out.println(list2);}
    }
    

在这里插入图片描述

3.1获取Stream流

  • Stream流是一个接口

    在这里插入图片描述

    package stream;import java.util.*;
    import java.util.stream.Stream;public class demo2 {public static void main(String[] args) {// 1.获取stream流// 获取集合里的stream流可以调用stream方法List<String> list = new ArrayList<>();Stream<String> s1 = list.stream();// 2.mapMap<String, Integer> map = new HashMap<>();// 获取键流Stream<String> s2 = map.keySet().stream();// 获取值流Stream<Integer> s3 = map.values().stream();// 获取键值对流  entrySet把map转为set集合Stream<Map.Entry<String, Integer>> s4 = map.entrySet().stream();Set<Map.Entry<String, Integer>> test = new HashMap<String, Integer>().entrySet();// 3.数组 两种方式String[] arr = {"hello", "world", "java"};Stream<String> s5 = Arrays.stream(arr);System.out.println(s5.count());  // 计数System.out.println(s5.max(Comparator.comparingInt(String::length)));Stream<String> s6 = Stream.of("hello", "world", "java");}
    }
    

3.2处理stream流

在这里插入图片描述

  • 返回值是一个新流

    package stream;import java.util.ArrayList;
    import java.util.List;
    import java.util.Objects;
    import java.util.stream.Stream;public class demo3 {public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("hello");list.add("world");list.add("java");list.add("hello");// 1.过滤方法    foreach将每个遍历出的元素塞给方法内。list.stream().filter(name -> name.startsWith("h") && name.length() != 1).forEach(System.out::println);// 2.排序方法List<Double> list1 = new ArrayList<>();list1.add(1.2);list1.add(2.3);list1.add(3.4);list1.add(1.2);// double可以排是因为里面实现了compare方法  默认是升序list1.stream().sorted().forEach(System.out::println);System.out.println("------------------");list1.stream().sorted((s1, s2) -> Double.compare(s2, s1)).forEach(System.out::println);// 只要前两名System.out.println("------------------");list1.stream().sorted().limit(2).forEach(System.out::println);// 跳过前两名System.out.println("------------------");list1.stream().sorted().skip(2).forEach(System.out::println);// 去重 如果需要自定义对象能够去重要重写hashCode和equals方法System.out.println("------------------");list.stream().distinct().forEach(System.out::println);// 映射方法, 把原来的数据拿出来加工并返回新流System.out.println("------------------");list1.stream().map(s -> s * 2).forEach(System.out::println);// 合并List<String> list2 = new ArrayList<>();list2.add("hello");list2.add("world");list2.add("java");Stream<String> list3 = list2.stream();Stream<String> list4 = list2.stream();Stream<String> s3 = Stream.concat(list4, list3);System.out.println(s3.count());}
    }
    
  • 如果需要自定义对象能够去重要重写hashCode和equals方法

  • 映射方法, 把原来的数据拿出来加工并返回新流

  • 都是一个个方法,记住就好,看源码收益低

3.3终结stream流

在这里插入图片描述

  • 抽象方法就是没实现的方法

    package stream;import java.util.ArrayList;
    import java.util.List;
    import java.util.Optional;public class demo4 {public static void main(String[] args) {// 创建一个教师列表并添加教师对象List<Teacher> teachers = new ArrayList<>();teachers.add(new Teacher("张三", 18, 3000));teachers.add(new Teacher("李四", 19, 4000));teachers.add(new Teacher("王五", 20, 5000));teachers.add(new Teacher("赵六", 21, 6000));teachers.add(new Teacher("钱七", 22, 7000));// 使用流的收集操作:// 过滤出工资大于4000的教师,并打印他们的信息teachers.stream().filter(teacher -> teacher.getSalary() > 4000) // 过滤条件.forEach(System.out::println); // 打印符合条件的教师,自动调用toString方法// countlong count = teachers.stream().filter(teacher -> teacher.getSalary() > 4000).count();System.out.println("~~~~~~~~~~~~~~");// 放到Optional<T>中防止空指针异常Optional<Teacher> max = teachers.stream().max(Teacher::compareTo);Teacher teacher = max.get();System.out.println(teacher.getName() + " " + teacher.getAge() + " " + teacher.getSalary());}
    }
    

在这里插入图片描述

  • 添加到集合中

    package stream;import java.util.*;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;public class demo4 {public static void main(String[] args) {// 收集到数组或者集合上List<String> test = new ArrayList<>();test.add("hello");test.add("world");Stream<String> s1 = test.stream().filter(s -> s.length() > 1);// 收集到List集合// Collectors.toList()返回一个ArrayList对象,明确调用了一个Collector的实现,明确使用ArrayList调用方法List<String> list = s1.collect(Collectors.toList());System.out.println(list);System.out.println("~~~~~~~~~~~~~~");// 收集到Set集合,流终止后不能再使用List<String> test2 = new ArrayList<>();test2.add("hello");test2.add("world");Set<String> set = test2.stream().filter(s -> s.length() > 1).collect(Collectors.toSet());System.out.println(set);// 收集到数组中 两个版本的toArray,参数是数组的构造器,默认返回的类型是Object[]Stream<String> s2 = test2.stream().filter(s -> s.length() > 1);String[] arr = s2.toArray(String[]::new);// Objects[] arr1 = s2.toArray();System.out.println(Arrays.toString(arr));// 收集到Map集合中,需要指定key和value的类型,否则会报错List<Teacher> list2 = new ArrayList<>();list2.add(new Teacher("张三", 18, 3000));list2.add(new Teacher("李四", 19, 4000));list2.add(new Teacher("王五", 20, 5000));list2.add(new Teacher("赵六", 21, 6000));list2.add(new Teacher("钱七", 22, 7000));Map<String, Integer> map = list2.stream().collect(Collectors.toMap(Teacher::getName, Teacher::getAge));System.out.println(map);}
    }
    
  • 在这里插入图片描述

  • 可以看到toList调用的是ArrayList

  • 每个方法都有默认的构造方法,按需调用即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/6941.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

如何在 uniapp 中实现图形验证码

全篇大概2000 字&#xff08;含代码&#xff09;&#xff0c;建议阅读时间10分钟。 什么是图形验证码&#xff1f; 图形验证码&#xff08;也称为图片验证码或验证码图像&#xff09;通常用于防止机器人自动提交表单&#xff0c;确保用户是人工操作。 一、需求 我们希望在一个…

基于 Java(SpringBoot)+MySQL 开发古诗词学习网站

古诗词系统设计与实现 引言 编写目的 为了保证项目团队按时保质地完成项目目标&#xff0c;便于项目团队成员更好地了解项目情况&#xff0c;使项目工作开展的各个过程合理有序&#xff0c;有必要以文件化的形式&#xff0c;把对于在项目生命周期内的工作任务范围、各项工作…

基于JavaWeb+MySQL实现口算题卡

爱 math 口算题卡 1. 总体要求 综合运用软件工程的思想&#xff0c;协同完成一个软件项目的开发&#xff0c;掌软件工程相关的技术和方法&#xff1b;组成小组进行选题&#xff0c;通过调研完成项目的需求分析&#xff0c;并详细说明小组成员的分工、项目的时间管理等方面。根…

Sibyl:提升复杂现实世界推理能力的LLM智能体框架

人工智能咨询培训老师叶梓 转载标明出处 大模型&#xff08;LLMs&#xff09;以其卓越的问题解决能力而闻名&#xff0c;这主要归功于它们内在的知识储备、强大的上下文学习能力以及零样本&#xff08;zero-shot&#xff09;能力。然而&#xff0c;这些基于LLM的智能体在长期推…

Jest项目实战(4):将工具库顺利迁移到GitHub的完整指南

开源代码&#xff1a;将工具库迁移到GitHub 随着项目的成熟和完善&#xff0c;将其开源不仅可以获得更多的用户和贡献者&#xff0c;还能促进项目本身的发展。GitHub作为全球最大的开源协作平台&#xff0c;自然成为了大多数开发者的首选。本文将引导您完成将工具库迁移至GitH…

ai面试辅助工具有哪些

目前市场上常见的AI面试辅助工具包括以下几款‌&#xff1a; ‌白瓜面试‌&#xff1a;这是一款专为在线面试和笔试场景设计的AI助手&#xff0c;支持实时语音识别、图片识别、智能辅助回答等功能&#xff0c;适用于多种岗位和面试平台‌ ‌Interview‌&#xff1a;这是一款基…

Redis - Zset 有序集合

一、基本认识 有序集合相对于字符串、列表、哈希、集合来说会有⼀些陌⽣。它保留了集合不能有重复成员的 特点&#xff0c;但与集合不同的是&#xff0c;有序集合中的每个元素都有⼀个唯⼀的浮点类型的分数&#xff08;score&#xff09;与之关 联&#xff0c;着使得有序集合中…

Linux下的WatchDog

看门狗&#x1f415; 看门狗简介 看门狗定时器&#xff08;Watchdog Timer&#xff09;是一种定时器&#xff0c;用于检测系统是否正常运行。如果系统在规定时间内没有向看门狗定时器发送复位信号&#xff0c;看门狗定时器就会产生复位信号&#xff0c;使系统复位。看门狗定时…

vue3+vite搭建脚手架项目本地运行electron桌面应用

1.搭建脚手架项目 搭建Vue3ViteTs脚手架-CSDN博客 2.创建完项目后&#xff0c;安装所需依赖包 npm i vite-plugin-electron electron26.1.0 3.根目录下创建electron/main.ts electron/main.ts /** electron/main.ts */import { app, BrowserWindow } from "electron&qu…

推荐一款基于Flash的交互式园林设计工具:Garden Planner

Garden Planner是一款由Artifact Interactive开发的基于Flash的交互式园林设计工具。它允许用户以拖放的方式安排植物、树木、建筑物和各种对象&#xff0c;使园林规划变得简单直观。此外&#xff0c;Garden Planner提供工具来快速创建铺路、路径和围栏&#xff0c;帮助用户设计…

H7-TOOL的LUA小程序教程第17期:扩展驱动AD7606, ADS1256,MCP3421, 8路继电器和5路DS18B20(2024-11-01)

LUA脚本的好处是用户可以根据自己注册的一批API&#xff08;当前TOOL已经提供了几百个函数供大家使用&#xff09;&#xff0c;实现各种小程序&#xff0c;不再限制Flash里面已经下载的程序&#xff0c;就跟手机安装APP差不多&#xff0c;所以在H7-TOOL里面被广泛使用&#xff…

JAVA基础:数组 (习题笔记)

一&#xff0c;编码题 1&#xff0c;数组查找操作&#xff1a;定义一个长度为10 的一维字符串数组&#xff0c;在每一个元素存放一个单词&#xff1b;然后运行时从命令行输入一个单词&#xff0c;程序判断数组是否包含有这个单词&#xff0c;包含这个单词就打印出“Yes”&…

为开源 AI 模型引入激励机制?解读加密 AI 协议 Sentient 的大模型代币化解决方案

撰文&#xff1a;Shlok Khemani 编译&#xff1a;Glendon&#xff0c;Techub News 古时候&#xff0c;中国人深信「阴阳」的概念——宇宙的每一个方面都蕴含着内在的二元性&#xff0c;这两种相反的力量不断地相互联系&#xff0c;形成一个统一的整体。就好比女性代表「阴」&a…

ONES 功能上新|ONES Project 甘特图全面升级

ONES Project 甘特图全面升级&#xff0c;提供更加专业、灵活的工具。 项目经理往往面临项目进度难以直观把控、关键任务容易遗漏、里程碑节点缺乏明确标记、进度偏差无法及时发现等挑战。 针对这些痛点&#xff0c;ONES 新增了关键路径、基线对比、里程碑视图、交付物视图等 1…

windows 进程降权和提权代码示例(2) c++

强制完整性控制 - Win32 应用程序 |Microsoft 学习 一、强制完整性控制 品03/26/20217 个参与者 反馈 本文内容 诚信标签进程创建强制性政策 强制完整性控制 &#xff08;MIC&#xff09; 提供了一种用于控制对安全对象的访问的机制。此机制是对自主访问控制的补充&#xff…

基于Python的旅游景点推荐系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

【C++】vector 类深度解析:探索动态数组的奥秘

&#x1f31f;快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。 &#x1f31f; 如果你对string类还存在疑惑&#xff0c;欢迎阅读我之前的作品 &#xff1a; &#x1f449;【C】string 类深度解析&#xff1a;…

Hugging Face 平台轻松上手 | 书生大模型

文章目录 HF 的 Transformers 库GitHub CodeSpace 使用终端安装依赖下载 internlm2_5-7b-chat 的配置文件 参考文献 HF 的 Transformers 库 直接使用预训练模型进行推理提供了大量预训练模型可供使用使用预训练模型进行迁移学习 因此在使用 HF 前&#xff0c;我们需要下载 Tra…

项目升级到.Net8.0 Autofac引发诡异的问题

前两天把项目升级到.Net8.0了&#xff0c;把.Net框架升级了&#xff0c;其他一些第三方库升级了一部分&#xff0c;升级完以后项目跑不起来了&#xff0c;报如下错误&#xff1a; An unhandled exception occurred while processing the request. DependencyResolutionExcepti…

如何开发查找附近地点的微信小程序

我开发的是找附近卫生间的小程序。 在现代城市生活中&#xff0c;找到一个干净、方便的公共卫生间有时可能是一个挑战。为了解决这个问题&#xff0c;我们可以开发一款微信小程序&#xff0c;帮助用户快速找到附近的卫生间。本文将介绍如何开发这样一款小程序&#xff0c;包…