函数式接口和stream

news2024/12/27 13:55:54

函数式接口(Functional Interface)是Java 8引入的一个新特性,它只有一个抽象方法的接口。这意味着你可以将一个函数式接口作为参数传递给方法,或者将其实现为一个lambda表达式。函数式接口的主要目的是允许你以声明性方式处理操作,比如函数的传递和返回。

函数式接口的特点包括:

1. **只有一个抽象方法**:这是函数式接口的核心特征,它确保了接口可以被用作lambda表达式的类型。

2. **可以有多个默认方法或静态方法**:除了一个抽象方法外,函数式接口还可以包含默认方法和静态方法。

3. **可以被隐式转换为lambda表达式**:由于只有一个抽象方法,Java编译器可以自动推断出lambda表达式中的参数和返回值。

4. **常用于实现函数式编程**:函数式接口是实现函数式编程的基础,它允许你以函数的方式处理数据和逻辑。

Java中一些内置的函数式接口包括:

- `java.util.function.Function<T,R>`:接受一个参数并返回一个结果。
- `java.util.function.Predicate<T>`:接受一个参数并返回一个布尔值。
- `java.util.function.Consumer<T>`:接受一个参数并执行某些操作,但不返回结果。
- `java.util.function.Supplier<T>`:不接受参数,返回一个结果。
- `java.util.function.BiFunction<T,U,R>`:接受两个参数并返回一个结果。

使用函数式接口可以简化代码,提高代码的可读性和可维护性。例如,你可以使用`java.util.stream.Stream`API来处理集合,其中就大量使用了函数式接口。
 

Java 8中引入了许多函数式接口,它们都位于`java.util.function`包中。以下是一些常用的函数式接口:

1. **`Supplier<T>`**:给定无参数,返回一个结果。
   ```java
   T get()
   ```

2. **`Consumer<T>`**:接受一个参数,执行某些操作,但不返回结果。
   ```java
   void accept(T t)
   ```

3. **`Predicate<T>`**:接受一个参数,并返回一个布尔值。
   ```java
   boolean test(T t)
   ```

4. **`Function<T,R>`**:接受一个参数,并返回一个结果。
   ```java
   R apply(T t)
   ```

5. **`BiFunction<T,U,R>`**:接受两个参数,并返回一个结果。
   ```java
   R apply(T t, U u)
   ```

6. **`UnaryOperator<T>`**:是`Function<T,T>`的子接口,接受一个参数,并返回相同类型的结果。
   ```java
   T apply(T t)
   ```

7. **`BinaryOperator<T>`**:是`BiFunction<T,T,T>`的子接口,接受两个相同类型的参数,并返回相同类型的结果。
   ```java
   T apply(T t1, T t2)
   ```

8. **`Comparator<T>`**:用于比较两个参数,并返回一个整数值。
   ```java
   int compare(T o1, T o2)
   ```

9. **`BiPredicate<T,U>`**:接受两个参数,并返回一个布尔值。
   ```java
   boolean test(T t, U u)
   ```

10. **`BiConsumer<T,U>`**:接受两个参数,并执行某些操作,但不返回结果。
    ```java
    void accept(T t, U u)
    ```

11. **`ToDoubleFunction<T>`**:接受一个参数,并返回一个`double`类型的结果。
    ```java
    double applyAsDouble(T value)
    ```

12. **`ToIntFunction<T>`**:接受一个参数,并返回一个`int`类型的结果。
    ```java
    int applyAsInt(T value)
    ```

13. **`ToLongFunction<T>`**:接受一个参数,并返回一个`long`类型的结果。
    ```java
    long applyAsLong(T value)
    ```

14. **`DoubleUnaryOperator`**:接受一个`double`类型的参数,并返回一个`double`类型的结果。
    ```java
    double applyAsDouble(double value)
    ```

15. **`IntUnaryOperator`**:接受一个`int`类型的参数,并返回一个`int`类型的结果。
    ```java
    int applyAsInt(int value)
    ```

16. **`LongUnaryOperator`**:接受一个`long`类型的参数,并返回一个`long`类型的结果。
    ```java
    long applyAsLong(long value)
    ```

17. **`DoubleBinaryOperator`**:接受两个`double`类型的参数,并返回一个`double`类型的结果。
    ```java
    double applyAsDouble(double left, double right)
    ```

18. **`IntBinaryOperator`**:接受两个`int`类型的参数,并返回一个`int`类型的结果。
    ```java
    int applyAsInt(int left, int right)
    ```

19. **`LongBinaryOperator`**:接受两个`long`类型的参数,并返回一个`long`类型的结果。
    ```java
    long applyAsLong(long left, long right)
    ```

这些函数式接口为Java 8中的Lambda表达式和方法引用提供了基础,使得代码更加简洁和表达式化。
 

在Java 8中,`Stream`流是一种高级迭代器,它允许你以声明性方式处理数据集合。`Stream`提供了一种对集合对象进行一系列操作的新方式,这些操作可以是中间操作(如`filter`、`map`、`sorted`等)和终止操作(如`forEach`、`reduce`、`collect`等)。`Stream`流可以对数据序列执行各种操作,如筛选、转换、聚合等,而无需显式编写复杂的循环代码。

`Stream`流的主要特点包括:

1. **不可变性**:一旦创建了流,就不能再修改原始的元素集合。

2. **惰性求值**:流上的操作不会立即执行,而是在需要结果时才执行。

3. **可消费性**:流只能被消费一次。一旦完成,流就会失效,除非重新生成。

4. **并行能力**:流可以很容易地并行处理数据,以提高性能。

5. **类型安全**:流操作都是类型安全的,这意味着它们在编译时就会检查类型错误。

6. **函数式编程**:流与函数式接口紧密集成,允许你使用Lambda表达式作为参数。

`Stream`流的常见操作包括:

- **创建流**:可以通过多种方式创建流,如通过集合的`stream()`方法,数组的`Arrays.stream()`方法,或者通过`Stream`类的静态方法(如`of`、`iterate`、`generate`)。

- **中间操作**:这些操作会返回一个新的流,可以进行链式操作。例如:
  - `filter`:根据条件过滤元素。
  - `map`:将流中的每个元素映射到另一个元素。
  - `flatMap`:将流中的每个元素替换为目标元素的流,然后将多个流连接成一个流。
  - `sorted`:将流中的元素进行排序。

- **终止操作**:这些操作会消耗流,并产生一个最终的结果或副作用。例如:
  - `forEach`:对流中的每个元素执行操作。
  - `reduce`:通过某个连接动作将所有元素汇总成一个汇总结果。
  - `collect`:将流转换成其他形式(如集合)。

- **短路操作**:某些终止操作在找到结果后会立即停止处理剩余的元素。例如`anyMatch`、`allMatch`、`noneMatch`。

使用`Stream`流可以提高代码的可读性和性能,特别是在处理大型数据集时。它允许开发者以声明性方式表达复杂的操作,而无需编写繁琐的循环和条件语句。

重复注解机制是Java 8引入的一个新特性,它允许在同一声明类型(类、属性或方法)上多次使用同一个注解。在Java 8之前,相同的注解在同一位置只能使用一次,不能使用多次。Java 8通过引入`@Repeatable`注解支持了重复注解机制,使得相同的注解可以在同一地方使用多次。

具体来说,要实现重复注解,需要定义一个注解,并使用`@Repeatable`元注解来标记它,`@Repeatable`的参数是一个容器注解,该容器注解用于存储重复的注解实例。例如,如果有一个注解`@Hint`,想要让它成为可重复的,可以这样定义:

```java
@Repeatable(Hints.class)
@interface Hint {
    String value();
}

@interface Hints {
    Hint[] value();
}
```

在Java 8之前,如果要应用多个相同的注解,需要使用一个容器注解来包含这些注解,然后将容器注解应用到元素上。而在Java 8中,可以直接在元素上多次使用相同的注解,如:

```java
@Hint("hint1")
@Hint("hint2")
class Person {}
```

这样,`Person`类就同时被`@Hint`注解标记了两次,分别带有值"hint1"和"hint2"。这种机制简化了代码,提高了可读性,并且在框架设计中特别有用,因为它允许为相同的元素标记多个不同的注解,实现更灵活的注解使用方式。
 

函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。

函数式接口可以被隐式转换为 lambda 表达式。

Lambda 表达式和方法引用(实际上也可认为是Lambda表达式)上。

如定义了一个函数式接口如下:

@FunctionalInterface
interface GreetingService 
{
    void sayMessage(String message);
}

那么就可以使用Lambda表达式来表示该接口的一个实现(注:JAVA 8 之前一般是用匿名类实现的):

GreetingService greetService1 = message -> System.out.println("Hello " + message);

函数式接口可以对现有的函数友好地支持 lambda。

JDK 1.8 之前已有的函数式接口:

  • java.lang.Runnable
  • java.util.concurrent.Callable
  • java.security.PrivilegedAction
  • java.util.Comparator
  • java.io.FileFilter
  • java.nio.file.PathMatcher
  • java.lang.reflect.InvocationHandler
  • java.beans.PropertyChangeListener
  • java.awt.event.ActionListener
  • javax.swing.event.ChangeListener

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

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

相关文章

Oracle 高水位线和低-高水位线(High Water Mark Low High Water Mark)

在Oracle的逻辑存储结构中&#xff08;表空间-段-区-块&#xff09;&#xff0c;数据是存在数据段中的&#xff0c;通常一个表就是一个数据段&#xff0c;而段最终又由许多数据块组成。当数据存入数据块时&#xff0c;需要对块进行格式化&#xff0c;高水位线&#xff08;High …

科技资讯|Matter 1.4 标准正式发布,低功耗蓝牙助力其发展

连接标准联盟&#xff08;CSA&#xff09;宣布推出最新的 Matter 1.4 版本&#xff0c;引入了一系列新的设备类型和功能增强&#xff0c;有望提高包括 HomeKit 在内的智能家居生态系统之间的互操作性。 设备供应商和平台能够依靠增强的多管理员功能改善多生态系统下的用户体验&…

python练习-Django web入门

python -m pip install --user requests使用API调用请求数据 处理API响应 import requestsclass Requests:def request(self):url "https://www.toutiao.com/stream/widget/local_weather/data/?city北京"headers {"Accept": "application/json;…

元器件封装

元器件封装类型 为什么越来越多用贴片元件&#xff0c;而不是插件元件 为什么越来越多用贴片元件&#xff0c;而不是插件元件 1.体积小、质量小、容易保存和运输&#xff1b; 2.容易焊接和拆卸。抗震效果好。 贴片元件不用过孔&#xff0c;用锡少。直插元件最麻烦的就是拆卸&a…

[SaaS] 数禾科技 AIGC生成营销素材

https://zhuanlan.zhihu.com/p/923637935https://zhuanlan.zhihu.com/p/923637935

自顶向下逐步求精解决LeetCode第3307题找出第K个字符II题

3307.找出第K个字符II 难度&#xff1a;困难 问题描述&#xff1a; Alice和Bob正在玩一个游戏。最初&#xff0c;Alice有一个字符串word"a"。 给定一个正整数k和一个整数数组operations&#xff0c;其中operations[i]表示第i次操作的类型。 现在Bob将要求Alice按…

v-html 富文本中图片使用element-ui image-viewer组件实现预览,并且阻止滚动条

效果 导入组件 import ElImageViewer from "element-ui/packages/image/src/image-viewer"; components:{ ElImageViewer },模板使用组件 <el-image-viewerv-if"isShowPics":on-close"closeViewer":url-list"srcList"/>定义两…

Redis - 哨兵(Sentinel)

Redis 的主从复制模式下&#xff0c;⼀旦主节点由于故障不能提供服务&#xff0c;需要⼈⼯进⾏主从切换&#xff0c;同时⼤量 的客⼾端需要被通知切换到新的主节点上&#xff0c;对于上了⼀定规模的应⽤来说&#xff0c;这种⽅案是⽆法接受的&#xff0c; 于是Redis从2.8开始提…

使用wordpress搭建简易的信息查询系统

背景 当前有这样的一个需求&#xff0c;要实现让客户能够自助登录系统查询一些个人的信息&#xff0c;市面上没有特别符合我的需求的产品&#xff0c;经过一段时间的研究&#xff0c;想出了一个用wordpress实现简易信息查询系统&#xff0c;有两种方式。 方式一&#xff1a;使…

探索 Python HTTP 的瑞士军刀:Requests 库

文章目录 探索 Python HTTP 的瑞士军刀&#xff1a;Requests 库第一部分&#xff1a;背景介绍第二部分&#xff1a;Requests 库是什么&#xff1f;第三部分&#xff1a;如何安装 Requests 库&#xff1f;第四部分&#xff1a;Requests 库的基本函数使用方法第五部分&#xff1a…

【青牛科技】 GC6153——TMI8152 的不二之选,可应用于摇头机等产品中

在电子工程领域&#xff0c;不断寻求性能更优、成本更低的解决方案是工程师们的永恒追求。今天&#xff0c;我们要为广大电子工程师带来一款极具竞争力的产品 —— GC6153&#xff0c;它将成为 TMI8152 的完美替代之选。 一、产品背景 随着科技的飞速发展&#xff0c;电子设备…

基于yolov8、yolov5的番茄成熟度检测识别系统(含UI界面、训练好的模型、Python代码、数据集)

摘要&#xff1a;番茄成熟度检测在农业生产及质量控制中起着至关重要的作用&#xff0c;不仅能帮助农民及时采摘成熟的番茄&#xff0c;还为自动化农业监测提供了可靠的数据支撑。本文介绍了一款基于YOLOv8、YOLOv5等深度学习框架的番茄成熟度检测模型&#xff0c;该模型使用了…

艾体宝干货丨微突发流量检测与分析:IOTA让网络监控更精准

网络流量中的微突发问题常常难以察觉&#xff0c;但它们可能对网络性能产生显著影响。这篇文章深入探讨了如何利用IOTA来捕捉和分析微突发&#xff0c;帮助您快速有效地解决网络中的突发流量问题。 什么是微突发&#xff08;Microburst&#xff09;流量&#xff1f; 微突发是…

论文略读: ALPAGASUS: TRAINING A BETTER ALPACA WITH FEWER DATA

ICLR 2024 1 背景 大模型通常需要在有监督指令数据集上进行指令微调来加强指令遵循能力 但是广泛使用的数据集包含许多具有不正确或不相关响应的低质量样本&#xff0c;这对大模型微调具有误导性——>论文提出了一种简单有效的数据选择策略&#xff0c;使用ChatGPT自动识别…

【Android】ANR监控治理技术方案

一、 背景 1、 bugly针对crash监控做的比较好&#xff0c;但是对anr监控&#xff0c;早期版本监听 /data/anr 目录的变化可以拿到数据&#xff0c;但是现在高版本已经没有权限监听此目录&#xff0c;当前数据非常少&#xff0c;结合历次数据来看对我们解决ANR问题没有任何帮助…

FreeRTOS学习11——时间片任务调度

时间片任务调度 时间片任务调度 时间片任务调度 概念&#xff1a;时间片调度主要针对优先级相同的任务&#xff0c;当多个任务的优先级相同时&#xff0c;任务调度器会在每一次系统时钟节拍到的时候切换任务&#xff0c;也就是说 CPU 轮流运行优先级相同的任务&#xff0c;每个…

怎么把模糊照片变清晰?4种方法助你修复图片清晰度!

在我们的日常生活中&#xff0c;模糊的图片常常成为影响视觉体验的一大障碍&#xff0c;无论是由于时间久远导致老照片分辨率降低&#xff0c;还是拍摄时因手抖造成的画面模糊&#xff0c;都会让我们的图片质量大打折扣。为了帮助你解决这一困扰&#xff0c;我们为你整理了四种…

Pytorch学习--神经网络--完整的模型验证套路

一、选取的图片 全部代码依托于该博客 二、代码&#xff08;调用训练好的模型&#xff09; import torch import torchvision from PIL import Image from model import *img_path "dog.png" image Image.open(img_path)print(image.size)transform torchvisi…

力扣 LeetCode 454. 四数相加II(Day3:哈希表)

解题思路&#xff1a; 使用map 四个数组两两一组 前两个数组的各个值遍历相加&#xff0c;和为key&#xff0c;出现的次数为value 后两个数组的各个值遍历相加&#xff0c;如果该值的负数能在map中找到&#xff08;表示能抵消为0&#xff0c;符合题意四数之和为0&#xff0…

期权懂|交易股票期权该怎么操作?又该如何开户?

期权小懂每日分享期权知识&#xff0c;帮助期权新手及时有效地掌握即市趋势与新资讯&#xff01; 交易股票期权该怎么操作&#xff1f;又该如何开户&#xff1f; 一、交易股票期权主要包括以下几个步骤&#xff1a; &#xff08;1&#xff09;选择交易平台‌&#xff1a; 选择…