提交 af8631ed 编写于 作者: W wizardforcel

2020-05-21 17:26:53

上级 a61564d4
......@@ -86,7 +86,7 @@ public class HelloWorld
在上述`HelloWorld`的示例中,变量`format`被声明为`default`,因此可以由存在`HelloWorld.java`的同一程序包中的所有类访问。
#### 1.4 私
#### 1.4 私
专用访问修饰符是最严格的访问级别。 (最高级)类和接口不能是私有的。 **私有成员仅可在同一类中访问。** 声明为私有的方法,变量和构造器只能在声明的类本身内访问。
......
......@@ -127,7 +127,7 @@ public Employee() {
```
## 私建筑商
## 私建筑商
有时您想保护构造器以免被其他类调用。 总之,您希望没有人能够创建该类的新实例。
......
......@@ -4,7 +4,7 @@
**Java 实例**运算符(也称为类型比较[运算符](https://howtodoinjava.com/java/basics/operators-in-java/))用于测试对象是否为指定类型(类,子类或接口)的实例。
它返回
它返回
* **是**-如果变量是指定类的实例,则它是父类或实现指定接口或父接口
* **否**-如果变量不是类的实例或接口的实现; 或变量为空
......
......@@ -27,7 +27,7 @@ Java 提供**类型包装器**,它们是**封装对象内原始类型**的类
## 2\. 何时使用包装器类
在场景中使用 Java 包装器类
在场景中使用 Java 包装器类
* 当两个方法要引用基本类型的相同实例时,请将包装器类作为方法参数传递。
* Java 中的泛型仅适用于对象,不支持原始类型。
......@@ -38,7 +38,7 @@ Java 提供**类型包装器**,它们是**封装对象内原始类型**的类
#### 3.1 包装器类的原始类型
有两种方法可以将原始类型转换为相应包装类的对象
有两种方法可以将原始类型转换为相应包装类的对象
1. 使用**构造器**
2. 使用**静态工厂方法**(例如`valueOf()`)(字符除外)
......
......@@ -6,7 +6,7 @@
**同步的**关键字有助于编写应用程序的[并发](https://howtodoinjava.com/java-concurrency-tutorial/)部分,以保护此块中的共享资源。
`synchronized`关键字可以与
`synchronized`关键字可以与
* 一个代码块
* 一个方法
......@@ -117,7 +117,7 @@ TWO :: 3
#### 2.2 内部工作
与同步块类似,线程必须使用同步方法来获取关联的监视对象上的锁。 如果采用同步方法,则锁定对象为
与同步块类似,线程必须使用同步方法来获取关联的监视对象上的锁。 如果采用同步方法,则锁定对象为
* **'.class'对象**-如果该方法是静态的。
* **'此'对象**-如果方法不是静态的。 “ this”是指在其中调用同步方法的当前对象的引用。
......
......@@ -111,7 +111,7 @@ Future result is - - 2; And Task done is true
```
在这里,我们使用`submit()`方法发送了一个`Callable`对象,该对象将在执行程序中执行。 此方法接收`Callable`对象作为参数,并返回一个`Future`对象,我们可以将其用于两个主要目标
在这里,我们使用`submit()`方法发送了一个`Callable`对象,该对象将在执行程序中执行。 此方法接收`Callable`对象作为参数,并返回一个`Future`对象,我们可以将其用于两个主要目标
1. **我们可以控制任务的状态** – 我们可以取消任务并检查任务是否完成。 为此,我们使用`isDone()`方法检查任务是否完成。
2. **We can get the result returned by the call() method**. For this purpose, we have used the `get()` method. This method waits until the `Callable` object has finished the execution of the `call()` method and has returned its result.
......
......@@ -14,7 +14,7 @@ ArrayList 层次结构
## 1\. ArrayList 功能
ArrayList 具有以下功能
ArrayList 具有以下功能
1. **有序** – arraylist 中的元素保留其顺序,默认情况下是其添加到列表的顺序。
2. **基于索引的** – 可以使用索引位置随机访问元素。 索引以`'0'`开头。
......
......@@ -8,7 +8,7 @@
## 1\. 使用 java.io.File 类创建文件
使用[`File.createNewFile()`](https://docs.oracle.com/javase/7/docs/api/java/io/File.html#createNewFile())方法创建新文件。 此方法返回布尔值
使用[`File.createNewFile()`](https://docs.oracle.com/javase/7/docs/api/java/io/File.html#createNewFile())方法创建新文件。 此方法返回布尔值
* `true`如果文件创建成功。
* `false`如果文件已经存在或由于某种原因操作失败。
......
......@@ -204,6 +204,6 @@ public class ReadStreamIntoStringUsingScanner
就这样。 这篇文章的目的是为特定目的提供快速链接,即**将输入流读取到字符串**中。
[**Download Sourcecode**](https://docs.google.com/file/d/0B7yo2HclmjI4MjI3VlR5RkpTU0U/edit?usp=sharing)
[**下载源码**](https://docs.google.com/file/d/0B7yo2HclmjI4MjI3VlR5RkpTU0U/edit?usp=sharing)
学习愉快!
\ No newline at end of file
......@@ -6,7 +6,7 @@
## 1\. TemporalQuery 接口
[TemporalQuery](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/TemporalQuery.html) 是一个功能接口,因此可以用作 [lambda 表达式](https://howtodoinjava.com/java8/lambda-expressions/)[方法参考](https://howtodoinjava.com/java8/lambda-method-references-example/)的分配目标。 方法`queryForm()`使用时间对象查询并返回查询的值。
[TemporalQuery](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/TemporalQuery.html) 是一个函数式接口,因此可以用作 [lambda 表达式](https://howtodoinjava.com/java8/lambda-expressions/)[方法参考](https://howtodoinjava.com/java8/lambda-method-references-example/)的分配目标。 方法`queryForm()`使用时间对象查询并返回查询的值。
该实现定义查询的逻辑,并负责记录该逻辑。 它可以使用`TemporalAccessor`上的任何方法来确定结果。
......
......@@ -204,7 +204,7 @@ G1 跟踪每个区域包含的实时数据量。 此信息用于确定包含最
## 总结
因此,在此 **Java 垃圾回收教程**中,我们学习了以下内容
因此,在此 **Java 垃圾回收教程**中,我们学习了以下内容
1. 对象生命周期分为三个阶段,即对象创建,对象使用和对象销毁。
2. `mark-sweep``mark-sweep-compact``mark-copy`机制如何运作。
......
......@@ -21,7 +21,7 @@ Table of Contents
[Java 中的内存管理](http://www.oracle.com/technetwork/java/javase/memorymanagement-whitepaper-150215.pdf "java memory management")是垃圾收集器的职责。 这与 Java 之前的实践相反,在 Java 之前,程序员负责分配程序中的内存。
正式而言,**垃圾收集器负责**
正式而言,**垃圾收集器负责**
* 分配内存
* 确保所有引用的对象都保留在内存中,并且
......
......@@ -12,7 +12,7 @@
## 1.1 方法返回类型
此方法的结果为整数值,其中
此方法的结果为整数值,其中
1. **正整数** – 表示字符串对象在字典上跟随自变量字符串。
2. **负整数** – 表示按字典顺序在自变量字符串之前的字符串对象。
......
......@@ -8,7 +8,7 @@
## 1\. charAt()方法参数
唯一的方法参数是`index`。 它必须是`int`类型。 <codex>索引</codex>参数必须为
唯一的方法参数是`index`。 它必须是`int`类型。 <codex>索引</codex>参数必须为
1. 等于大于“ 0”
2. 少于字符串字符的长度,即`str.length()-1`
......
......@@ -8,7 +8,7 @@
加拿大邮政编码是一个六位字符的字符串,构成加拿大邮政地址的一部分。
有效的加拿大邮政编码为
有效的加拿大邮政编码为
* 格式为 A1A 1A1,其中 A 是字母,1 是数字。
* 用空格分隔第三个和第四个字符。
......
......@@ -145,7 +145,7 @@ JDK 附带的几个重要组件如下:
## 5\. JDK,JRE 和 JVM 之间的区别
基于以上讨论,我们可以得出以下三个方面的关系
基于以上讨论,我们可以得出以下三个方面的关系
> JRE = JVM + 运行 Java 应用程序的库。
>
......
......@@ -2,7 +2,7 @@
> 原文: [https://howtodoinjava.com/java9/stream-api-improvements/](https://howtodoinjava.com/java9/stream-api-improvements/)
通过示例了解[](https://docs.oracle.com/javase/9/docs/api/java/util/stream/Stream.html) API(即`takeWhile` / `dropWhile`方法,`ofNullable``iterate`方法)中 Java 9 的新改进。
通过示例了解[](https://docs.oracle.com/javase/9/docs/api/java/util/stream/Stream.html) API(即`takeWhile`/`dropWhile`方法,`ofNullable``iterate`方法)中 Java 9 的新改进。
```java
Table of Contents
......@@ -17,16 +17,16 @@ New Stream ofNullable() method
新方法`takeWhile``dropWhile`允许您基于谓词获取流的一部分。 这里的流可以是有序的也可以是无序的,所以:
1. 在有序流上,`takeWhile`返回从流中获取的,与给定谓词匹配的元素的“最长前缀”,从流的开头开始。
2. 在无序流上,`takeWhile`从流的开头开始返回与给定谓词(但不是全部)匹配的流元素的子集
2. 在无序流上,`takeWhile`返回与给定谓词(但不是全部)匹配的流元素的子集,从流的开头开始
`dropWhile`方法与`takeWhile`方法相反。
1. 在有序流上,`dropWhile`返回“最长前缀”之后与给定谓词匹配的其余项。
1. 在有序流上,`dropWhile`返回“最长前缀”之后与给定谓词匹配的其余项。
2. 在无序流上,`dropWhile`在删除与给定谓词匹配的元素子集后返回剩余的流元素。
#### `takeWhile`和`dropWhile`示例
在此示例中,我们具有从“ a”到“ i”的字符列表。 我希望所有可能在迭代中出现在字符“ d”之前的字符。
在此示例中,我们具有从`a``i`的字符列表。 我希望所有可能在迭代中出现在字符`d`之前的字符。
```java
List<String> alphabets = List.of("a", "b", "c", "d", "e", "f", "g", "h", "i");
......@@ -115,7 +115,7 @@ Output:
在 Java 8 之前,流中不能具有`null`值。 会导致`NullPointerException`
在 Java 9 中,`ofNullable`方法使您可以创建**单元素流**,该流将包装一个值(如果不为 null),否则为空流。
在 Java 9 中,`ofNullable`方法使您可以创建**单元素流**,该流将包装一个值(如果不为`null`),否则为空流。
```java
Stream<String> stream = Stream.ofNullable("123");
......
......@@ -14,7 +14,7 @@ Create Immutable Map
## 创建不可变列表
使用`List.of()`静态工厂方法创建不可变列表。 它具有以下不同的重载版本
使用`List.of()`静态工厂方法创建不可变列表。 它具有以下不同的重载版本
```java
static <E> List<E> of()
......@@ -34,7 +34,7 @@ static <E> List<E> of(E... elements)
这些方法创建的`List`实例具有以下特征:
1. 这些列表是不可变的。 不能在这些列表中添加,删除或替换元素。 调用任何 mutator 方法(即 add,addAll,clear,remove,removeAll,replaceAll)将始终导致抛出`UnsupportedOperationException`
1. 这些列表是不可变的。 不能在这些列表中添加,删除或替换元素。 调用任何可变方法(即`add``addAll``clear``remove``removeAll``replaceAll`)将始终导致抛出`UnsupportedOperationException`
2. 它们不允许`null`元素。 尝试添加`null`元素将导致`NullPointerException`
3. 如果所有元素都是可序列化的,它们可以[可序列化的](//howtodoinjava.com/java/serialization/a-mini-guide-for-implementing-serializable-interface-in-java/)
4. 列表中元素的顺序与提供的参数或提供的数组中的元素的顺序相同。
......@@ -70,10 +70,10 @@ Output:
## 创建不可变集
`Set`的行为与`List`非常相似,只是差异很小。 例如
`Set`的行为与`List`非常相似,只是差异很小。 例如
1. `Set`也不允许[重复元素](//howtodoinjava.com/puzzles/find-duplicate-elements-in-an-array/)。 传递的任何重复元素将导致`IllegalArgumentException`
2. set 元素的迭代顺序未指定,可能会发生变化。
2. 集合元素的迭代顺序未指定,可能会发生变化。
所有`Set`工厂方法都具有与`List`相同的签名。
......@@ -119,7 +119,7 @@ public class ImmutableCollections {
## 创建不可变映射
`Map`工厂方法与`List``Set`重载工厂方法相同。 唯一的区别是方法的签名采用交替的键和值作为参数。 例如
`Map`工厂方法与`List``Set`重载工厂方法相同。 唯一的区别是方法的签名采用交替的键和值作为参数。 例如
```java
static <K,V> Map<K,V> of()
......
......@@ -2,7 +2,7 @@
> 原文: [https://howtodoinjava.com/java9/java9-private-interface-methods/](https://howtodoinjava.com/java9/java9-private-interface-methods/)
从 Java 9 开始,您可以在接口中包含私有方法。 使用私有方法,现在也可以在接口中封装[封装](//howtodoinjava.com/object-oriented/encapsulation-in-java-and-its-relation-with-abstraction/)
从 Java 9 开始,您可以在接口中包含私有方法。 使用私有方法,现在也可以在接口中实现[封装](//howtodoinjava.com/object-oriented/encapsulation-in-java-and-its-relation-with-abstraction/)
在此 Java 9 教程中,我们将详细了解**接口私有方法**
......@@ -84,7 +84,7 @@ static method
```
[Access modifier](//howtodoinjava.com/object-oriented/java-access-modifiers/) ‘public’ is optional in all above interface method declarations. I have added them to improve readability only.
[访问修饰符](//howtodoinjava.com/object-directional/java-access-modifiers/)`public`在以上所有接口方法声明中都是可选的。 我添加它们只是为了提高可读性。
## 自 Java 9 以来的私有方法
......@@ -94,7 +94,7 @@ static method
在接口中使用私有方法有四个规则:
1. 专用接口方法不能是抽象的。
1. 接口私有方法不能是抽象的。
2. 私有方法只能在接口内部使用。
3. 私有静态方法可以在其他静态和非静态接口方法中使用。
4. 私有非静态方法不能在私有静态方法内部使用。
......@@ -150,13 +150,13 @@ static method
```
## Java 9 专用接口方法示例
## Java 9 接口私有方法示例
让我们看一个演示,以了解专用接口方法的用法。
让我们看一个演示,以了解接口私有方法的用法。
我正在创建具有两个功能的计算器类。 第一个函数将接受一些整数并将所有偶数相加。 第二个函数将接受一些整数并将所有奇数相加。
#### CustomCalculator.java – 接口
#### `CustomCalculator.java` – 接口
```java
import java.util.function.IntPredicate;
......@@ -181,7 +181,7 @@ public interface CustomCalculator
```
#### Main.java – 类
#### `Main.java` – 类
```java
public class Main implements CustomCalculator {
......@@ -211,11 +211,12 @@ Output:
让我们回顾一下 Java 9 中所有允许的方法类型。
| 方法类型 | 从何时起 |
| 公共摘要 | Java 7 |
| 公开违约 | Java 8 |
| --- | --- |
| 公共抽象 | Java 7 |
| 公开默认 | Java 8 |
| 公共静态 | Java 8 |
| 私人的 | Java 9 |
| 私静态 | Java 9 |
| 私 | Java 9 |
| 私静态 | Java 9 |
将您的问题放在评论部分中。
......@@ -223,4 +224,4 @@ Output:
参考: [JEP 213](https://openjdk.java.net/jeps/213)
[Download Sourcecode](//howtodoinjava.com/wp-content/downloads/Java9-interface-private-methods.zip)
\ No newline at end of file
[下载源码](//howtodoinjava.com/wp-content/downloads/Java9-interface-private-methods.zip)
\ No newline at end of file
......@@ -2,7 +2,7 @@
> 原文: [https://howtodoinjava.com/java-8-tutorial/](https://howtodoinjava.com/java-8-tutorial/)
**Java 8 教程**列出了重要的 **Java 8 功能**,并提供了此发行版中引入的示例。 所有功能均具有指向详细教程的链接,例如 lambda 表达式,Java 流,功能接口和日期时间 API 更改。
**Java 8 教程**列出了重要的 **Java 8 功能**,并提供了此发行版中引入的示例。 所有功能均具有指向详细教程的链接,例如 lambda 表达式,Java 流,函数式接口和日期时间 API 更改。
**Java SE 8**[于 2014 年初发布的](https://blogs.oracle.com/thejavatutorials/jdk-8-is-released)。 在 Java 8 中,最受关注的功能是 lambda 表达式。 它还具有许多其他重要功能,例如默认方法,流 API 和新的日期/时间 API。 让我们通过示例了解 Java 8 中的*这些新功能。*
......@@ -39,14 +39,14 @@ or
```
请注意,根据 x 和 y 的类型,方法可能会在多个地方使用。 参数可以匹配 int 或 Integer 或简单地也可以匹配 String。 根据上下文,它将添加两个整数或连接两个字符串。
请注意,根据`x``y`的类型,方法可能会在多个地方使用。 参数可以匹配`int``Integer`或简单地也可以匹配`String`。 根据上下文,它将添加两个整数或连接两个字符串。
#### 编写 Lambda 表达式的规则
1. Lambda 表达式可以具有零个,一个或多个参数。
2. 参数的类型可以显式声明,也可以从上下文中推断出来。
3. 多个参数用强制括号括起来,并用逗号分隔。 空括号用于表示空参数集。
4. 当有单个参数时,如果推断出其类型,则不强制使用括号。 例如 a->返回 a * a
4. 当有单个参数时,如果推断出其类型,则不强制使用括号。 例如`a -> a * a`
5. Lambda 表达式的主体可以包含零个,一个或多个语句。
6. 如果 lambda 表达式的主体具有单个语句,则不必使用大括号,并且匿名函数的返回类型与主体表达式的返回类型相同。 如果正文中的语句多于一个,则这些语句必须用大括号括起来。
......@@ -54,9 +54,9 @@ or
## 2\. 函数式接口
功能接口也称为*单一抽象方法接口(SAM 接口)*。 顾名思义,它们**允许其中恰好是一种抽象方法**。 Java 8 引入了一个注解,即`@FunctionalInterface`,当您注解的接口违反功能接口的约定时,该注解可用于编译器级错误。
函数式接口也称为*单一抽象方法接口(SAM 接口)*。 顾名思义,它们**允许其中恰好是一种抽象方法**。 Java 8 引入了一个注解,即`@FunctionalInterface`,当您注解的接口违反函数式接口的约定时,该注解可用于编译器级错误。
典型的功能接口示例:
典型的函数式接口示例:
```java
@FunctionalInterface
......@@ -66,11 +66,11 @@ public interface MyFirstFunctionalInterface {
```
请注意,即使省略`@FunctionalInterface`注释,功能接口也有效。 它仅用于通知编译器在接口内部强制执行单个抽象方法。
请注意,即使省略`@FunctionalInterface`注释,函数式接口也有效。 它仅用于通知编译器在接口内部强制执行单个抽象方法。
另外,由于默认方法不是抽象的,因此*可以随意向功能接口添加任意数量的默认方法*
另外,由于默认方法不是抽象的,因此*可以随意向函数式接口添加任意数量的默认方法*
要记住的另一个重要点是,如果接口声明了一个覆盖`java.lang.Object`的公共方法之一的抽象方法,那么该接口的任何实现都将具有`java.lang.Object`的实现,因此这也不会计入接口的抽象方法数量。 例如,下面是完全有效的功能接口。
要记住的另一个重要点是,如果接口声明了一个覆盖`java.lang.Object`的公共方法之一的抽象方法,那么该接口的任何实现都将具有`java.lang.Object`的实现,因此这也不会计入接口的抽象方法数量。 例如,下面是完全有效的函数式接口。
```java
@FunctionalInterface
......@@ -87,7 +87,7 @@ public interface MyFirstFunctionalInterface
```
> 阅读更多: [Java 8 功能接口教程](//howtodoinjava.com/java8/functional-interface-tutorial/)
> 阅读更多: [Java 8 函数式接口教程](//howtodoinjava.com/java8/functional-interface-tutorial/)
## 3\. 默认方法
......@@ -106,7 +106,7 @@ public interface Moveable {
```
`Moveable`接口定义了一种方法`move()`,并提供了默认实现。 如果有任何类实现了此接口,则无需实现其自己的`move()`方法版本。 它可以直接调用`instance.move()`。 例如
`Moveable`接口定义了一种方法`move()`,并提供了默认实现。 如果有任何类实现了此接口,则无需实现其自己的`move()`方法版本。 它可以直接调用`instance.move()`。 例如
```java
public class Animal implements Moveable{
......@@ -126,9 +126,9 @@ Output: I am moving
## 4\. Java 8 流
引入的另一项重大更改是 **Java 8 Streams API** ,它提供了一种以各种方式处理一组数据的机制,这些方式可以包括过滤,转换或任何其他可能对应用程序有用的方式。
引入的另一项重大更改是 **Java 8 API** ,它提供了一种以各种方式处理一组数据的机制,这些方式可以包括过滤,转换或任何其他可能对应用程序有用的方式。
Java 8 中的 Streams API 支持不同类型的迭代,您可以在其中简单地定义要处理的项目集,对每个项目执行的操作,以及存储这些操作的输出。
Java 8 中的 API 支持不同类型的迭代,您可以在其中简单地定义要处理的项目集,对每个项目执行的操作,以及存储这些操作的输出。
流 API 的示例。 在此示例中,`items``String`值的集合,您想删除以某些前缀文本开头的条目。
......@@ -139,7 +139,7 @@ List<String> filteredList = items.stream().filter(e -> (!e.startsWith(prefix))).
```
这里`items.stream()`表示我们希望使用 Streams API 处理`items`集合中的数据。
这里`items.stream()`表示我们希望使用 API 处理`items`集合中的数据。
> 阅读更多: [Java 8 内部和外部迭代](//howtodoinjava.com/java8/java-8-tutorial-internal-vs-external-iteration/)
......@@ -149,13 +149,13 @@ List<String> filteredList = items.stream().filter(e -> (!e.startsWith(prefix))).
#### 日期
`Date`类甚至已过时。 打算替换 Date 类的新类是`LocalDate``LocalTime``LocalDateTime`
`Date`类甚至已过时。 打算替换`Date`类的新类是`LocalDate``LocalTime``LocalDateTime`
1. `LocalDate`类表示日期。 没有时间或时区的表示。
2. `LocalTime`类表示时间。 没有日期或时区的表示。
3. `LocalDateTime`类表示日期时间。 没有时区的表示。
如果您想将日期功能与区域信息一起使用,则 Lambda 会为您提供额外的 3 类,类似于上面的一种,即`OffsetDate``OffsetTime``OffsetDateTime`。 时区偏移可以以“ +05:30”或“欧洲/巴黎”格式表示。 这是通过使用另一个类即`ZoneId`完成的。
如果您想将日期功能与区域信息一起使用,则 Lambda 会为您提供额外的 3 类,类似于上面的一种,即`OffsetDate``OffsetTime``OffsetDateTime`。 时区偏移可以以“`+05:30`”或“`Europe/Paris`”格式表示。 这是通过使用另一个类即`ZoneId`完成的。
```java
LocalDate localDate = LocalDate.now();
......@@ -187,7 +187,7 @@ duration = Duration.ofMinutes(10);
```
`Duration`处理较小的时间单位,例如毫秒,秒,分钟和小时。 它们更适合与应用程序代码进行交互。 要与人互动,您需要使**持续时间更长**,该类与`Period`类一起提供。
`Duration`处理较小的时间单位,例如毫秒,秒,分钟和小时。 它们更适合与应用程序代码进行交互。 要与人互动,您需要使**持续时间更长**,该类与`Period`类一起提供。
```java
Period period = Period.ofDays(6);
......
......@@ -99,11 +99,11 @@ c -> { //some complex statements } // takes a collection and do some procesing
因此,我们简要了解了什么是 lambda 表达式。 如果您感到迷茫且无法联系,请耐心等待,如何在 Java 编程语言中使用它。 我们将在接下来的 30 分钟内解决所有问题。 让我们开始吧。
在深入研究 lambda 表达式和 Java 编程之间的关系之前,您还必须了解**功能接口**。 这太重要了。
在深入研究 lambda 表达式和 Java 编程之间的关系之前,您还必须了解**函数式接口**。 这太重要了。
## 2\. Java 8 功能接口
## 2\. Java 8 函数式接口
**单一抽象方法接口**(SAM 接口)不是一个新概念。 这意味着**仅使用一种方法**进行接口。 在 Java 中,我们已经有许多此类 SAM 接口的示例。 从 Java 8 开始,它们也将**也称为功能接口**。 Java 8 通过使用新的注释(即 **@FunctionalInterface** )标记这些接口来实现单一职责规则。
**单一抽象方法接口**(SAM 接口)不是一个新概念。 这意味着**仅使用一种方法**进行接口。 在 Java 中,我们已经有许多此类 SAM 接口的示例。 从 Java 8 开始,它们也将**也称为函数式接口**。 Java 8 通过使用新的注释(即 **@FunctionalInterface** )标记这些接口来实现单一职责规则。
例如,Runnable 接口的新定义是这样的:
......@@ -115,11 +115,11 @@ public interface Runnable {
```
如果尝试在任何功能接口中添加新方法,则编译器将不允许您执行此操作,并且会引发编译时错误。
如果尝试在任何函数式接口中添加新方法,则编译器将不允许您执行此操作,并且会引发编译时错误。
到目前为止,一切都很好。 但是,**它们与 Lambda 表达式有何关系?** 让我们找出答案。
我们知道 Lambda 表达式是不带名称的匿名函数,它们(大多数)作为参数传递给其他函数。 好吧,在 Java 方法中,参数总是具有类型,并且在确定方法重载甚至是简单方法调用的情况下,都会寻找此类型信息以确定需要调用哪个方法。 因此,基本上每个 lambda 表达式也必须都可以转换为某种类型才能被接受为方法参数。 好吧,用于转换 lambda 表达式的**类型始终是功能接口类型**
我们知道 Lambda 表达式是不带名称的匿名函数,它们(大多数)作为参数传递给其他函数。 好吧,在 Java 方法中,参数总是具有类型,并且在确定方法重载甚至是简单方法调用的情况下,都会寻找此类型信息以确定需要调用哪个方法。 因此,基本上每个 lambda 表达式也必须都可以转换为某种类型才能被接受为方法参数。 好吧,用于转换 lambda 表达式的**类型始终是函数式接口类型**
让我们通过一个例子来理解它。 如果我们必须编写一个在控制台上打印“ howtodoinjava”的线程,那么最简单的代码将是:
......@@ -144,7 +144,7 @@ new Thread(
```
我们还看到 Runnable 是具有单个方法 run()的功能接口。 因此,当您将 lambda 表达式传递给 Thread 类的构造器时,编译器将尝试将该表达式转换为等效的 Runnable 代码,如第一个代码示例所示。 如果编译器成功,则一切运行良好,如果编译器无法将表达式转换为等效的实现代码,它将抱怨。 在此,在上面的示例中,lambda 表达式被转换为 Runnable 类型。
我们还看到 Runnable 是具有单个方法 run()的函数式接口。 因此,当您将 lambda 表达式传递给 Thread 类的构造器时,编译器将尝试将该表达式转换为等效的 Runnable 代码,如第一个代码示例所示。 如果编译器成功,则一切运行良好,如果编译器无法将表达式转换为等效的实现代码,它将抱怨。 在此,在上面的示例中,lambda 表达式被转换为 Runnable 类型。
In simple words, a lambda expression is an instance of a functional interface. But a lambda expression itself does not contain the information about which functional interface it is implementing; that information is deduced from the context in which it is used.
......
# Java 8 – 功能接口
# Java 8 – 函数式接口
> 原文: [https://howtodoinjava.com/java8/functional-interface-tutorial/](https://howtodoinjava.com/java8/functional-interface-tutorial/)
了解 Java 8 功能接口以及围绕一个接口允许的一种抽象方法的规则。 了解如何通过功能接口中的默认方法添加更多方法。
了解 Java 8 函数式接口以及围绕一个接口允许的一种抽象方法的规则。 了解如何通过函数式接口中的默认方法添加更多方法。
```java
Table of Contents
......@@ -14,9 +14,9 @@ Table of Contents
## 1\. 什么是函数式接口
功能接口是 [**java 8**](//howtodoinjava.com/category/java8/ "java 8") 中的新增功能,其中**恰好允许其中的一种抽象方法**。 这些接口也称为**单一抽象方法接口(SAM 接口)**
函数式接口是 [**java 8**](//howtodoinjava.com/category/java8/ "java 8") 中的新增功能,其中**恰好允许其中的一种抽象方法**。 这些接口也称为**单一抽象方法接口(SAM 接口)**
在 Java 8 中,功能接口也可以使用 lambda 表达式,方法引用和构造器引用表示。
在 Java 8 中,函数式接口也可以使用 lambda 表达式,方法引用和构造器引用表示。
Java 8 也引入了一个注解,即 **@FunctionalInterface** ,当您注解的接口违反了一种抽象方法的约定时,该注解也可用于编译器级错误。
......@@ -54,17 +54,17 @@ multiple non-overriding abstract methods found in interface MyFirstFunctionalInt
![Functional-Interface-Error](img/b2a2ca3ede69d478e2b572229eff6507.png)
> 阅读更多:[通用功能接口](https://howtodoinjava.com/java8/generic-functional-interfaces/)
> 阅读更多:[通用函数式接口](https://howtodoinjava.com/java8/generic-functional-interfaces/)
## 2\. 函数式接口中的“是”与“不”
以下是函数式接口中允许和不允许的事物的列表。
* 如上所述, ***在任何功能接口中仅允许使用一种抽象方法*** 。 在功能接口中不允许使用第二种抽象方法。 如果删除 **@FunctionInterface** 注解,则可以添加另一个抽象方法,但是它将使该接口成为非功能性接口。
* 即使`@FunctionalInterface`注释将被省略 ,功能接口也是 ***有效。 它仅用于通知编译器在接口内部强制使用单个[抽象方法](//howtodoinjava.com/object-oriented/exploring-interfaces-and-abstract-classes-in-java/ "Exploring interfaces and abstract classes in java")。***
* 如上所述, ***在任何函数式接口中仅允许使用一种抽象方法*** 。 在函数式接口中不允许使用第二种抽象方法。 如果删除 **@FunctionInterface** 注解,则可以添加另一个抽象方法,但是它将使该接口成为非功能性接口。
* 即使`@FunctionalInterface`注释将被省略 ,函数式接口也是 ***有效。 它仅用于通知编译器在接口内部强制使用单个[抽象方法](//howtodoinjava.com/object-oriented/exploring-interfaces-and-abstract-classes-in-java/ "Exploring interfaces and abstract classes in java")。***
* Conceptually, a functional interface has exactly one abstract method. Since [**default methods**](//howtodoinjava.com/java8/default-methods-in-java-8/ "Default methods in java 8") have an implementation, they are not abstract. Since default methods are not abstract you’re ***free to add default methods to your functional interface as many as you like***.
以下是有效的功能接口:
以下是有效的函数式接口:
```java
@FunctionalInterface
......@@ -102,6 +102,6 @@ multiple non-overriding abstract methods found in interface MyFirstFunctionalInt
```
这就是 Java 8 中**功能接口的全部内容。**
这就是 Java 8 中**函数式接口的全部内容。**
学习愉快!
\ No newline at end of file
......@@ -2,7 +2,7 @@
> 原文: [https://howtodoinjava.com/java8/default-methods-in-java-8/](https://howtodoinjava.com/java8/default-methods-in-java-8/)
在上一篇文章中,我们了解了 [**Lambda 表达式和功能接口**](//howtodoinjava.com/java8/complete-lambda-expressions-tutorial-in-java/ "Complete lambda expressions tutorial") 。 现在,让我们继续进行讨论,并讨论另一个相关功能,即**默认方法**。 好吧,这对于 Java 开发人员来说确实是革命性的。 到 Java 7 为止,我们已经学到了很多关于接口的知识,而在编写代码或设计应用程序时,所有这些事情都已经牢记在心。 在引入默认方法之后,其中一些概念将从 Java 8 发生巨大变化。
在上一篇文章中,我们了解了 [**Lambda 表达式和函数式接口**](//howtodoinjava.com/java8/complete-lambda-expressions-tutorial-in-java/ "Complete lambda expressions tutorial") 。 现在,让我们继续进行讨论,并讨论另一个相关功能,即**默认方法**。 好吧,这对于 Java 开发人员来说确实是革命性的。 到 Java 7 为止,我们已经学到了很多关于接口的知识,而在编写代码或设计应用程序时,所有这些事情都已经牢记在心。 在引入默认方法之后,其中一些概念将从 Java 8 发生巨大变化。
```java
I will discuss following points in this post:
......@@ -72,7 +72,7 @@ Output: I am running
这是您下一个 [**面试问题**](//howtodoinjava.com/java-interview-questions/ "Java Interview Questions") 的不错的选择。 **最简单的答案是在 Java 中启用 lambda 表达式的功能。** Lambda 表达本质上是函数式接口的类型。 为了无缝支持 lambda 表达式,必须修改所有核心类。 但是,这些核心类(例如 java.util.List)不仅在 JDK 类中实现,而且在数千个客户端代码中也实现。 核心类中任何不兼容的更改都将肯定会产生反作用,并且根本不会被接受。
默认方法打破了这种僵局,并允许在核心类中添加对功能接口的支持。 让我们来看一个例子。 以下是已添加到 java.lang.Iterable 的方法。
默认方法打破了这种僵局,并允许在核心类中添加对函数式接口的支持。 让我们来看一个例子。 以下是已添加到 java.lang.Iterable 的方法。
```java
default void forEach(Consumer<? super T> action) {
......
......@@ -6,7 +6,7 @@
## Java 8 谓词用法
在 Java 8 中,[谓词](https://docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html)[功能接口](https://howtodoinjava.com/java8/functional-interface-tutorial/),因此可以用作 [**lambda 表达式**](//howtodoinjava.com/java8/complete-lambda-expressions-tutorial-in-java/ "Complete lambda expressions tutorial") 或方法参考的分配目标。 那么,您认为如何,我们可以在日常编程中使用这些 true / false 返回函数? 我会说,您可以在需要求值类似对象的组/集合上的条件的任何地方使用谓词,以便求值可以得出 true 或 false。
在 Java 8 中,[谓词](https://docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html)[函数式接口](https://howtodoinjava.com/java8/functional-interface-tutorial/),因此可以用作 [**lambda 表达式**](//howtodoinjava.com/java8/complete-lambda-expressions-tutorial-in-java/ "Complete lambda expressions tutorial") 或方法参考的分配目标。 那么,您认为如何,我们可以在日常编程中使用这些 true / false 返回函数? 我会说,您可以在需要求值类似对象的组/集合上的条件的任何地方使用谓词,以便求值可以得出 true 或 false。
例如,您可以在这些**实时用例**中使用 prdicates
......@@ -18,7 +18,7 @@
因此, **java 谓词**似乎很有趣。 让我们更深入。
如我所说,`Predicate`**功能接口**。 这意味着我们可以在需要谓词的任何地方传递 lambda 表达式。 例如,一种这样的方法是来自 [**流**](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html) 接口的`filter()`方法。
如我所说,`Predicate`**函数式接口**。 这意味着我们可以在需要谓词的任何地方传递 lambda 表达式。 例如,一种这样的方法是来自 [**流**](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html) 接口的`filter()`方法。
```java
/**
......@@ -38,7 +38,7 @@ Stream<T> filter(Predicate<? super T> predicate);
我们可以将流假定为一种机制,以创建支持顺序和并行聚合操作的元素序列。 这意味着我们可以随时通过一次调用收集并执行流中存在的所有元素的某些操作。
因此,从本质上讲,我们可以使用流和谓词来
因此,从本质上讲,我们可以使用流和谓词来
* 首先从组中过滤某些元素,然后
* 然后对过滤后的元素执行一些操作。
......
......@@ -8,7 +8,7 @@ Java 8 示例将内容导入文件。 您可以在链接的博客文章中找到
[BufferedWriter](https://docs.oracle.com/javase/8/docs/api/java/io/BufferedWriter.html) 用于将文本写入字符或字节流。 在打印字符之前,它将字符存储在缓冲区中并成束打印。 如果不进行缓冲,则每次调用 print()方法都会导致将字符转换为字节,然后将这些字节立即写入文件中,这可能会非常低效。
Java 程序*使用 Java 8* API 将内容写入文件
Java 程序*使用 Java 8* API 将内容写入文件
```java
//Get the file reference
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册