提交 0212f744 编写于 作者: W wizardforcel

2019-10-30 23:23:43

上级 2f35c5ca
此差异已折叠。
# Java InputStreamReader 教程
原文:http://zetcode.com/java/inputstreamreader/
Java InputStreamReader 教程显示了如何使用 Java `InputStreamReader`来读取 Java 中的文本。
## Java JavaInputStreamReader
`JavaInputStreamReader`是字节流和字符流之间的桥梁。 它读取字节,并使用指定的字符集将其解码为字符。
建议将`InputStreamReader`包裹在`BufferedReader`中以获得最佳效率。
请注意,在 Java 中使用字符流时,应避免使用依赖于默认编码的流,例如`FileReader``PrintWriter`
## Java InputStreamReader 文件流
在第一个示例中,我们使用`InputStreamReader`从文件流中读取文本。
`russiantext.txt`
```
Пе́рвая мирова́я война́ (28 июля 1914 — 11 ноября 1918) — один
из самых широкомасштабных вооружённых конфликтов в истории человечества.
Формальным поводом к войне послужили события в Сараеве,
где 28 июня 1914 года девятнадцатилетний боснийский серб, студент
Гаврило Принцип осуществил покушение, в результате которого был убит
австрийский эрцгерцог Франц Фердинанд и его морганатическая жена София Хотек.
```
我们有西里尔文文字。
`JavaInputStreamReaderEx.java`
```
package com.zetcode;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public class JavaInputStreamReaderEx {
public static void main(String[] args) throws FileNotFoundException, IOException {
String fileName = "src/main/resources/russiantext.txt";
try (FileInputStream fis = new FileInputStream(fileName);
InputStreamReader isr = new InputStreamReader(fis,
StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(isr)) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
}
}
```
该示例读取位于`src/main/resources`目录中的俄语小文本。
```
try (FileInputStream fis = new FileInputStream(fileName);
InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(isr)) {
```
`FileInputStream`用于创建文件流。 `FileInputStream`包装在`InputStreamReader`中,用于读取文本数据。 我们设置`StandardCharsets.UTF_8`编码。 最后,为了获得最佳效率,将`InputStreamReader`包装到`BufferedReader`中。
## Java InputStreamReader 标准输入流
第二个示例使用`InputStreamReader`从标准输入流读取文本。
`JavaInputStreamReaderEx2.java`
```
package com.zetcode;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
public class JavaInputStreamReaderEx2 {
public static void main(String[] args) throws IOException {
try (BufferedReader bin
= new BufferedReader(new InputStreamReader(System.in,
StandardCharsets.UTF_8))) {
String line;
System.out.print("Give me a cookie: ");
while (!(("cookie").equals(line = bin.readLine()))) {
System.out.println(line);
System.out.print("Give me a cookie: ");
}
}
}
}
```
该示例显示提示并等待用户的响应。 程序在收到正确的输入后结束。
```
try (BufferedReader bin
= new BufferedReader(new InputStreamReader(System.in))) {
```
我们使用`System.in`从标准输入中读取。
## Java InputStreamReader URL 流
下面的示例使用`InputStreamReader`从网络流中读取文本。
`JavaInputStreamReaderEx3.java`
```
package com.zetcode;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
public class JavaInputStreamReaderEx3 {
public static void main(String[] args) throws MalformedURLException, IOException {
StringBuilder sb;
URL url = new URL("http://www.something.com");
try (InputStreamReader isr = new InputStreamReader(url.openStream(),
StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(isr)) {
String line;
sb = new StringBuilder();
while ((line = br.readLine()) != null) {
sb.append(line);
sb.append(System.lineSeparator());
}
}
System.out.println(sb.toString());
}
}
```
该示例从网站读取文本。
```
try (InputStreamReader isr = new InputStreamReader(url.openStream(),
StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(isr)) {
```
该示例从指定的 URL 打开流。 它从`something.com`网页读取 HTML 代码。
下一个示例调用 Alexa Web 服务来确定网站的排名。
`JavaInputStreamReaderEx4.java`
```
package com.zetcode;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class JavaInputStreamReaderEx4 {
public static void main(String[] args) throws MalformedURLException,
IOException, ParserConfigurationException, SAXException {
String webSite = "www.something.com";
int ranking = 0;
String url = String.format("http://data.alexa.com/data?cli=10&url=%s",
webSite);
URLConnection conn = new URL(url).openConnection();
try (InputStream is = conn.getInputStream()) {
DocumentBuilder builder = DocumentBuilderFactory.newInstance()
.newDocumentBuilder();
Document doc = builder.parse(is);
Element element = doc.getDocumentElement();
NodeList nodeList = element.getElementsByTagName("POPULARITY");
if (nodeList.getLength() > 0) {
Element elementAttribute = (Element) nodeList.item(0);
ranking = Integer.valueOf(elementAttribute.getAttribute("TEXT"));
}
}
System.out.printf("Ranking of %s: %d%n", webSite, ranking);
}
}
```
该示例接收 XML 输入,并使用 Java DOM 解析器对其进行解析。
```
NodeList nodeList = element.getElementsByTagName("POPULARITY");
if (nodeList.getLength() > 0) {
Element elementAttribute = (Element) nodeList.item(0);
ranking = Integer.valueOf(elementAttribute.getAttribute("TEXT"));
}
```
该排名在`POPULARITY`标签的`TEXT`属性中可用。
在本教程中,我们展示了如何使用 Java `InputStreamReader`来读取 Java 中的文本。 您可能也对相关教程感兴趣: [Java FileInputStream 教程](/java/fileinputstream/)[Java InputStream 教程](/java/inputstream/)[用 Java 阅读文本文件](/articles/javareadtext/)[Jsoup 教程](/java/jsoup/)[Java 教程](/lang/java/)
\ No newline at end of file
# 读取 Java 中的文本文件
原文:http://zetcode.com/java/readtext/
在 Java 中阅读文本文件教程中,我们展示了如何在 Java 中阅读文本文件。 我们使用内置工具,包括`FileReader``InputStreamReader``Scanner`。 另外,我们使用 API​​ Google Guava 库。
Google Guava 是 Java 的通用库集; 该集合也包括 IO API。
以下示例使用此文本文件。
`src/resources/thermopylae.txt`
```
The Battle of Thermopylae was fought between an alliance of Greek city-states,
led by King Leonidas of Sparta, and the Persian Empire of Xerxes I over the
course of three days, during the second Persian invasion of Greece.
```
该文件位于`src/resources/`目录中。
## Java 读取文本类
我们可以使用以下 Java 类来读取 Java 中的文本文件。
* java.io.FileReader
* java.nio.file.Files
* java.util.Scanner
* java.io.InputStreamReader
* com.google.common.io.Files
## Java 使用 FileReader 读取文本文件
`FileReader`是用于读取字符文件的类。 它使用默认缓冲区大小从字符文件中读取文本。 从字节到字符的解码使用指定的字符集或平台的默认字符集。
**Note:** In the past, `FileReader` relied on the default platform's encoding. Since Java 11, the issue was corrected. It is possible now to explicitly specify the encoding.
`com/zetcode/FileReaderEx.java`
```
package com.zetcode;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class FileReaderEx {
public static void main(String[] args) throws IOException {
var fileName = "src/resources/thermopylae.txt";
try (BufferedReader br = new BufferedReader(
new FileReader(fileName, StandardCharsets.UTF_8))) {
var sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
sb.append(System.lineSeparator());
}
System.out.println(sb);
}
}
}
```
该代码示例从`thermopylae.txt`文件读取文本。
```
var fileName = "src/resources/thermopylae.txt";
```
`fileName`变量中,我们存储文件的路径。
```
try (BufferedReader br = new BufferedReader(
new FileReader(fileName, StandardCharsets.UTF_8))) {
```
`FileReader`将文件名作为第一个参数。 第二个参数是使用的字符集。 `FileReader`传递给`BufferedReader`,后者缓冲读取操作以获得更好的性能。 这是一个 try-with-resources 语句,可确保在语句末尾关闭资源(缓冲的读取器)。
```
var sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
sb.append(System.lineSeparator());
}
System.out.println(sb);
```
在控制台上打印行会占用更多资源。 因此,我们使用`StringBuilder`构建输出字符串并在一个操作中将其打印出来。 这是一个可选的优化。 `System.lineSeparator()`返回系统相关的行分隔符字符串。
## Java 使用 Files.readAllLines 读取文本文件
`Files.readAllLines()`方法从文件读取所有行。 此方法可确保在读取所有字节或引发异常后关闭文件。 使用指定的字符集将文件中的字节解码为字符。
请注意,此方法将整个文件读入内存。 因此,它可能不适用于非常大的文件。
`com/zetcode/ReadAllLinesEx.java`
```
package com.zetcode;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
public class ReadAllLinesEx {
public static void main(String[] args) throws IOException {
var fileName = "src/resources/thermopylae.txt";
List<String> lines = Files.readAllLines(Paths.get(fileName),
StandardCharsets.UTF_8);
for (String line : lines) {
System.out.println(line);
}
}
}
```
使用`Files.readAllLines()`方法读取`thermopylae.txt`文件的内容并将其打印到控制台。
## 使用 Java 8 流 API 读取文本文件
读取文本文件的另一种方法是使用 Java 8 流 API。 `Files.lines()`从文件中读取所有行作为流。 使用`StandardCharsets.UTF-8`字符集将文件中的字节解码为字符。
`com/zetcode/FilesLinesEx.java`
```
package com.zetcode;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class FilesLinesEx {
public static void main(String[] args) throws IOException {
var fileName = "src/resources/thermopylae.txt";
Files.lines(Paths.get(fileName)).forEachOrdered(System.out::println);
}
}
```
使用`Files.lines()`方法读取`thermopylae.txt`文件的内容并将其打印到控制台。
## Java 使用扫描仪读取文本文件
`Scanner`是简单的文本扫描器,可以使用正则表达式解析原始类型和字符串。
`com/zetcode/ScannerEx.java`
```
package com.zetcode;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class ScannerEx {
public static void main(String[] args) throws FileNotFoundException {
var fileName = "src/resources/thermopylae.txt";
try (var scanner = new Scanner(new File(fileName))) {
while (scanner.hasNext()) {
String line = scanner.nextLine();
System.out.println(line);
}
}
}
}
```
该示例使用`Scanner`读取文本文件。
```
while (scanner.hasNext()) {
String line = scanner.nextLine();
System.out.println(line);
}
```
使用`nextLine()`方法逐行读取文件。
## Java 使用 InputStreamReader 读取文本文件
`InputStreamReader`是从字节流到字符流的桥梁。 它读取字节,并使用指定的字符集将其解码为字符。
`com/zetcode/InputStreamReaderEx.java`
```
package com.zetcode;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
public class InputStreamReaderEx {
public static void main(String[] args) throws IOException {
var fileName = "src/resources/thermopylae.txt";
try (var br = new BufferedReader(new InputStreamReader(
new FileInputStream(fileName), StandardCharsets.UTF_8))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
}
}
```
该示例使用`InputStreamReader`读取文本文件。
```
try (var br = new BufferedReader(new InputStreamReader(
new FileInputStream(fileName), StandardCharsets.UTF_8))) {
```
`InputStreamReader`是从`FileInputStream`创建的,它通过打开与实际文件的连接来创建输入流。 然后将`InputStreamReader`传递给`BufferedReader`,以提高效率。
Java 7 引入了更方便的 API 来与`InputStreamReader`一起使用。 可以使用`Files.newBufferedReader`创建新的缓冲`InputStreamReader`
`com/zetcode/InputStreamReaderEx2.java`
```
package com.zetcode;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
public class InputStreamReaderEx2 {
public static void main(String[] args) throws IOException {
var fileName = "src/resources/thermopylae.txt";
var filePath = Paths.get(fileName);
try (BufferedReader br = Files.newBufferedReader(
filePath, StandardCharsets.UTF_8)) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
}
}
}
```
该示例使用`Files.newBufferedReader()`方法读取`thermopylae.txt`文件。
## Java 使用 Files.readAllBytes 读取文本文件
`Files.readAllBytes()`方法从文件读取所有字节。 它确保在读取所有字节后关闭文件。
`com/zetcode/ReadAllBytesEx.java`
```
package com.zetcode;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class ReadAllBytesEx {
public static void main(String[] args) throws IOException {
var fileName = "src/resources/thermopylae.txt";
var filePath = Paths.get(fileName);
byte[] data = Files.readAllBytes(filePath);
var content = new String(data);
System.out.println(content);
}
}
```
该示例从文件读取所有字节,并将它们传递给`String`构造函数。
## Java 使用 Files.readString 读取文本
Java 11 引入了一种方便的方法,该方法允许一次性将整个文件读取为字符串。
`Files.readString`将文件中的所有内容读取为字符串,并使用指定的或默认的(StandardCharsets.UTF_8)字符集将字节解码为字符。 它确保在读取所有内容后关闭文件。
`com/zetcode/ReadFileAsStringEx.java`
```
package com.zetcode;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class ReadFileAsStringEx {
public static void main(String[] args) throws IOException {
var fileName = "src/resources/thermopylae.txt";
var filePath = Paths.get(fileName);
var content = Files.readString(filePath);
System.out.println(content);
}
}
```
该示例将`thermopylae.txt`文件的内容读取为字符串,然后将其打印到终端。
## Java 使用 FileChannel 读取文本文件
`FileChannel`是用于读取,写入,映射和操作文件的通道。 文件通道的优点包括在文件的特定位置进行读写,加载文件的一部分或锁定文件的一部分。
`com/zetcode/FileChannelEx.java`
```
package com.zetcode;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class FileChannelEx {
public static void main(String[] args) throws IOException {
var fileName = "src/resources/thermopylae.txt";
try (RandomAccessFile myFile = new RandomAccessFile(fileName, "rw");
FileChannel inChannel = myFile.getChannel()) {
ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = inChannel.read(buf);
while (bytesRead != -1) {
buf.flip();
while (buf.hasRemaining()) {
System.out.print((char) buf.get());
}
buf.clear();
bytesRead = inChannel.read(buf);
}
}
}
}
```
该示例使用`FileChannel`读取文本文件。
```
try (RandomAccessFile myFile = new RandomAccessFile(fileName, "rw");
FileChannel inChannel = myFile.getChannel()) {
```
`RandomAccessFile`创建一个`FileChannle`
```
ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = inChannel.read(buf);
```
我们分配一个缓冲区并读取初始数据。
```
while (bytesRead != -1) {
buf.flip();
while (buf.hasRemaining()) {
System.out.print((char) buf.get());
}
buf.clear();
bytesRead = inChannel.read(buf);
}
```
我们将数据读入缓冲区并将其写入终端。 我们使用`flip()`将缓冲区从读取更改为写入。
## 使用 Google Guava 读取文本文件
Google Guava 是一个 Java 帮助程序库,也具有 IO 工具。 如果要读取的文件很大,则以下两个 Guava 方法将消耗大量系统资源。
`pom.xml`
```
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zetcode</groupId>
<artifactId>readtextguavaex</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>12</maven.compiler.source>
<maven.compiler.target>12</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.0-jre</version>
</dependency>
</dependencies>
</project>
```
这是 Maven POM 文件。
`com/zetcode/ReadTextGuavaEx.java`
```
package com.zetcode;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import java.io.File;
import java.io.IOException;
import java.util.List;
public class ReadTextGuavaEx {
public static void main(String[] args) throws IOException {
var fileName = "src/main/resources/thermopylae.txt";
List<String> lines = Files.readLines(new File(fileName),
Charsets.UTF_8);
var sb = new StringBuilder();
for (String line: lines) {
sb.append(line);
sb.append(System.lineSeparator());
}
System.out.println(sb);
}
}
```
在示例中,我们使用`Files.readLines()`方法从文件中读取所有行。 该方法返回字符串列表。 将默认字符集指定为第二个参数。
在第二个示例中,我们使用`Files.asCharSource()`
`com/zetcode/ReadTextGuavaEx2.java`
```
package com.zetcode;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import java.io.File;
import java.io.IOException;
public class ReadTextGuavaEx2 {
public static void main(String[] args) throws IOException {
var fileName = "src/main/resources/thermopylae.txt";
var charSource = Files.asCharSource(new File(fileName),
Charsets.UTF_8).read();
System.out.println(charSource);
}
}
```
`Files.asCharSource()`用于使用给定的字符集从给定的文件读取字符数据。 它的`read()`方法以字符串形式读取此源的内容。
在本文中,我们已经用 Java 的各种方式读取了文本文件。
您可能也对以下相关教程感兴趣: [Java 列表目录内容](/articles/javalistdirectory/)[Java FileOutputStream 教程](/java/fileoutputstream/)[用 Java 复制文件](/java/copyfile/)[Java 教程](/lang/java/)[使用 Java 8 的 StringJoiner](/articles/java8stringjoiner/)[连接字符串阅读 Java](/articles/javareadwebpage/)[Google Guava 简介](/articles/guava/)的网页。
列出[所有 Java 教程](/all/#java)
\ No newline at end of file
# Java Unix 时间
原文:http://zetcode.com/java/unixtime/
Java Unix 时间教程展示了如何使用 Java 计算 Unix 时间。
Unix 时间(也称为 POSIX 时间或纪元时间),是一种用于描述时间点的系统,该时间点定义为自 00:00:00 协调世界时(UTC)起经过的秒数 ,1970 年 1 月 1 日,星期四,减去此后发生的 of 秒数。
Unix 时间已广泛用于类似 Unix 的操作系统,但也用于许多其他计算系统和文件格式。 它是网站管理员经常使用的,因为 Unix 时间戳可以一次表示所有时区。
Unix 时间戳应存储为`long`数字; 如果将它们存储为 Java `int`值,则将导致 2038 年的问题。 32 位变量无法在 2038 年 1 月 19 日 UTC 时间 03:14:07 之后对时间进行编码。
```
$ date +%s
1517213809
```
我们可以使用`date`命令来确定 Linux 上的 Unix 时间。 Unix 时间可以在 [https://www.unixtimestamp.com/](https://www.unixtimestamp.com/) 上确定。
## Java Unix 时间示例
以下示例计算 Unix 时间。
`JavaUnixTimeEx.java`
```
package com.zetcode;
import java.time.Instant;
import java.util.Date;
public class JavaUnixTimeEx {
public static void main(String[] args) {
long ut1 = Instant.now().getEpochSecond();
System.out.println(ut1);
long ut2 = System.currentTimeMillis() / 1000L;
System.out.println(ut2);
Date now = new Date();
long ut3 = now.getTime() / 1000L;
System.out.println(ut3);
}
}
```
用 Java 计算 Unix 时间的三种基本方法。
```
long ut1 = Instant.now().getEpochSecond();
System.out.println(ut1);
```
从 Java 8 开始,可以使用`Instant`及其`getEpochSecond()`计算 Unix 时间。
```
long ut2 = System.currentTimeMillis() / 1000L;
System.out.println(ut2);
```
在这里,我们使用`System.currentTimeMillis()`方法计算 Unix 时间。 我们需要将毫秒转换为秒。
```
Date now = new Date();
long ut3 = now.getTime() / 1000L;
System.out.println(ut3);
```
我们还可以使用旧的`Date`类来计算 Unix 时间。
在本教程中,我们展示了如何使用 Java 计算 Unix 时间。 您可能也对相关教程感兴趣: [Java TemporalAdjusters 教程](/java/temporaladjusters/)[Java 文件教程](/java/file/)[Java LocalTime 教程](/java/localtime/)[Java 创建目录](/java/createdirectory/)[用 Java 复制文件](/java/copyfile/)[用 Java 创建文件](/java/createfile/)[Java 教程](/lang/java/)[用 Java 读取文本文件](/articles/javareadtext/)[读写 Java](/articles/javaico/) 中的 ICO 图像。
\ No newline at end of file
# Java LocalTime
原文:http://zetcode.com/java/localtime/
Java LocalTime 教程显示了如何在 Java 中使用 LocalTime。 我们计算当前的本地时间,解析本地时间,格式化本地时间,比较本地时间,并执行时间算法。
## Java LocalTime
LocalTime 是 ISO-8601 日历系统中没有时区的时间。 `LocalTime`是不可变的日期时间对象。
`LocalTime`不存储或表示日期或时区。 它是对壁钟上当地时间的描述。 挂钟时间,也称为现实世界时间或挂钟时间,是指由诸如手表或挂钟之类的计时器确定的经过时间。
比较应使用`equals()`方法。
## Java LocalTime 当前时间
使用`LocalTime.now()`检索当前时间。
`JavaLocalTimeNow.java`
```
package com.zetcode;
import java.time.LocalTime;
public class JavaLocalTimeNow {
public static void main(String[] args) {
LocalTime now = LocalTime.now();
System.out.println(now);
}
}
```
该示例显示本地当前时间。
```
18:12:05.172
```
这是输出。
## Java LocalTime 创建
有几种在 Java 中创建`LocalTime`的方法。
`JavaLocalTimeCreate.java`
```
package com.zetcode;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class JavaLocalTimeCreate {
public static void main(String[] args) {
// Current Time
LocalTime time1 = LocalTime.now();
System.out.println(time1);
// Specific Time
LocalTime time2 = LocalTime.of(7, 20, 45, 342123342);
System.out.println(time2);
// Specific Time
LocalTime time3 = LocalTime.parse("12:32:22",
DateTimeFormatter.ISO_TIME);
System.out.println(time3);
// Retrieving from LocalDateTime
LocalTime time4 = LocalDateTime.now().toLocalTime();
System.out.println(time4);
}
}
```
该示例提出了四种方法
```
LocalTime time1 = LocalTime.now();
```
`LocalTime.now()`创建当前本地时间。
```
LocalTime time2 = LocalTime.of(7, 20, 45, 342123342);
```
使用`LocalTime.of()`,我们可以创建一个小时,分钟,秒和纳秒的特定本地时间。
```
LocalTime time3 = LocalTime.parse("12:32:22",
DateTimeFormatter.ISO_TIME);
```
使用`LocalTime.parse()`,我们从字符串中解析`LocalTime`
```
LocalTime time4 = LocalDateTime.now().toLocalTime();
```
也可以从`LocalDateTime`对象获取`LocalTime`
```
18:18:12.135
07:20:45.342123342
12:32:22
18:18:12.186
```
This is the output.
## Java LocalTime 时,分,秒
下面的示例将本地时间分为小时,分钟和秒部分。
`JavaLocalTimeParts.java`
```
package com.zetcode;
import java.time.LocalTime;
public class JavaLocalTimeParts {
public static void main(String[] args) {
LocalTime time = LocalTime.now();
System.out.printf("Hour: %s%n", time.getHour());
System.out.printf("Minute: %s%n", time.getMinute());
System.out.printf("Second: %s%n", time.getSecond());
}
}
```
`getHour()`获得小时部分,`getMinute()`获得分钟部分,`getSecond()`获得`LocalTime`的第二部分。
```
Hour: 18
Minute: 25
Second: 55
```
This is the output.
## Java LocalTime 时区
我们可以计算特定时区的本地时间。 但是,`LocalTime`不存储时区信息。
`JavaLocalTimeZone.java`
```
package com.zetcode;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
public class JavaLocalTimeZone {
public static void main(String[] args) {
ZoneId zone1 = ZoneId.of("Europe/Bratislava");
ZoneId zone2 = ZoneId.of("Europe/Moscow");
LocalTime now1 = LocalTime.now(zone1);
LocalTime now2 = LocalTime.now(zone2);
System.out.printf("Bratislava time: %s%n", now1);
System.out.printf("Moscow time: %s%n", now2);
long hoursBetween = ChronoUnit.HOURS.between(now1, now2);
long minutesBetween = ChronoUnit.MINUTES.between(now1, now2);
System.out.println(hoursBetween);
System.out.println(minutesBetween);
}
}
```
该示例找出了莫斯科和布拉迪斯拉发的当前本地时间。 我们还计算了两个城市之间的时差。
```
ZoneId zone1 = ZoneId.of("Europe/Bratislava");
ZoneId zone2 = ZoneId.of("Europe/Moscow");
```
我们使用`ZoneId.of()`方法指定时区。
```
LocalTime now1 = LocalTime.now(zone1);
LocalTime now2 = LocalTime.now(zone2);
```
为了创建当地时间,我们将区域传递给`LocalTime.now()`
```
long hoursBetween = ChronoUnit.HOURS.between(now1, now2);
long minutesBetween = ChronoUnit.MINUTES.between(now1, now2);
```
我们以小时和分钟为单位计算两个城市之间的差异。
```
Bratislava time: 11:00:42.704
Moscow time: 13:00:42.732
2
120
```
This is the output.
## Java LocalTime 格式
不同国家/地区的时间格式不同。 `DateTimeFormatter`帮助我们格式化时间。
`JavaLocalTimeFormat.java`
```
package com.zetcode;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class JavaLocalTimeFormat {
public static void main(String[] args) {
LocalTime now = LocalTime.now();
DateTimeFormatter dtf = DateTimeFormatter.ISO_TIME;
System.out.println(now.format(dtf));
DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("hh:mm:ss");
System.out.println(now.format(dtf2));
DateTimeFormatter dtf3 = DateTimeFormatter.ofPattern("hh:mm:ss a");
System.out.println(now.format(dtf3));
}
}
```
该示例使用`DateTimeFormatter`格式化时间。
```
DateTimeFormatter dtf = DateTimeFormatter.ISO_TIME;
System.out.println(now.format(dtf));
```
我们将时间格式化为 ISO 格式的时间标准。
```
DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("hh:mm:ss");
```
我们可以使用`DateTimeFormatter.ofPattern()`选择特定的时间格式。 `DateTimeFormatter`的文档包含了我们可以使用的各种格式字符的描述。
```
11:08:56.483
11:08:56
11:08:56 AM
```
This is the output.
## Java LocalTime 算法
Java `LocalTime`具有执行时间算术的方法。
`JavaLocalTimeArithmetic.java`
```
package com.zetcode;
import java.time.LocalTime;
public class JavaLocalTimeArithmetic {
public static void main(String[] args) {
LocalTime now = LocalTime.now();
System.out.println("Current Time: " + now);
// LocalTime addition
System.out.println("Adding 3 hours: " + now.plusHours(3));
System.out.println("Adding 30 minutes: " + now.plusMinutes(30));
System.out.println("Adding 45 seconds: " + now.plusSeconds(45));
System.out.println("Adding 40000 nanoseconds: " + now.plusNanos(40000));
// LocalTime subtraction
System.out.println("Subtracting 3 hours: " + now.minusHours(3));
System.out.println("Subtracting 30 minutes: " + now.minusMinutes(30));
System.out.println("Subtracting 45 seconds: " + now.minusSeconds(45));
System.out.println("Subtracting 40000 nanoseconds: " + now.minusNanos(40000));
}
}
```
该示例介绍了添加和减去时间单位的方法。
```
System.out.println("Adding 3 hours: " + localTime.plusHours(3));
```
`plusHours()`将当前本地时间增加三个小时。
```
System.out.println("Subtracting 3 hours: " + now.minusHours(3));
```
同样,`minusHours()`从当前本地时间中减去三个小时。
```
Current Time: 11:12:51.155
Adding 3 hours: 14:12:51.155
Adding 30 minutes: 11:42:51.155
Adding 45 seconds: 11:13:36.155
Adding 40000 nanoseconds: 11:12:51.155040
Subtracting 3 hours: 08:12:51.155
Subtracting 30 minutes: 10:42:51.155
Subtracting 45 seconds: 11:12:06.155
Subtracting 40000 nanoseconds: 11:12:51.154960
```
This is the output.
## Java LocalTime 直到
使用`until()`方法,我们可以根据指定的单位计算到另一个时间的时间。
`JavaLocalTimeUntil.java`
```
package com.zetcode;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
public class JavaLocalTimeUntil {
public static void main(String[] args) {
LocalTime now = LocalTime.now();
LocalTime time = LocalTime.parse("22:15:30");
System.out.printf("%s hours%n", now.until(time, ChronoUnit.HOURS));
System.out.printf("%s minutes%n", now.until(time, ChronoUnit.MINUTES));
System.out.printf("%s seconds%n", now.until(time, ChronoUnit.SECONDS));
}
}
```
该示例以小时,分钟和秒为单位计算到另一个时间为止必须经过的时间。
```
System.out.printf("%s hours%n", now.until(time, ChronoUnit.HOURS));
```
使用`ChronoUnit.HOURS`,我们指定以小时为单位计算时间差。
```
10 hours
657 minutes
39476 seconds
```
这是示例的输出。
## Java LocalTime 比较
以下示例显示了如何比较时间。
`JavaLocalTimeCompare.java`
```
package com.zetcode;
import java.time.LocalTime;
public class JavaLocalTimeCompare {
public static void main(String[] args) {
LocalTime time1 = LocalTime.of(4, 23, 12);
LocalTime time2 = LocalTime.of(8, 03, 50);
LocalTime time3 = LocalTime.of(12, 47, 35);
if (time1.compareTo(time2) == 0) {
System.out.println("time1 and time2 are equal");
} else {
System.out.println("time1 and time2 are not equal");
}
if (time2.isBefore(time3)) {
System.out.println("time2 comes before time3");
} else {
System.out.println("time2 does not come before time3");
}
if (time3.isAfter(time1)) {
System.out.println("time3 comes after time1");
} else {
System.out.println("time3 does not come after time1");
}
}
}
```
该示例比较时间。 我们检查它们是否相等,是否在另一个时间之前或之后。
```
if (time1.compareTo(time2) == 0) {
```
`compareTo()`比较两个本地时间。
```
if (time2.isBefore(time3)) {
```
`isBefore()`检查时间是否在另一个时间之前。
```
if (time3.isAfter(time1)) {
```
`isAfter()`检查时间是否在另一个时间之后。
```
time1 and time2 are not equal
time2 comes before time3
time3 comes after time1
```
This is the output.
## Java LocalTime 截断
`LocalTime's` `truncatedTo()`方法返回具有被截断时间的本地时间的副本。
`JavaLocaTimeTruncate.java`
```
package com.zetcode;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
public class JavaLocaTimeTruncate {
public static void main(String[] args) {
LocalTime now = LocalTime.now();
System.out.println(now);
System.out.println(now.truncatedTo(ChronoUnit.HALF_DAYS));
System.out.println(now.truncatedTo(ChronoUnit.HOURS));
System.out.println(now.truncatedTo(ChronoUnit.MINUTES));
System.out.println(now.truncatedTo(ChronoUnit.SECONDS));
System.out.println(now.truncatedTo(ChronoUnit.MICROS));
}
}
```
该示例使用`truncatedTo()`将时间截断为半天,小时,分钟,秒和微秒。
```
11:27:56.309
00:00
11:00
11:27
11:27:56
11:27:56.309
```
This is the output.
在本教程中,我们使用了 Java LocalTime。 您可能也对相关教程感兴趣: [Java 教程](/lang/java/)[Java HashSet 教程](/java/hashset)[Java TemporalAdjusters 教程](/java/temporaladjusters/)[用 Java 阅读文本文件](/articles/javareadtext/)[用 Java](/articles/javaico/) 读写 ICO 图像。
\ No newline at end of file
# Java 斐波那契
原文:http://zetcode.com/java/fibonacci/
Java fibonacci 教程展示了如何计算 Java 中的 fibonacci 系列。 我们创建了几种计算斐波那契数列的算法。
斐波那契数列是一个值序列,每个值都是从 0 和 1 开始的两个前一个数字的和。因此,该序列的开头是:0、1、1、2、3, 5、8、13、21、34、55、89、144 ...
在本教程中,我们展示了几种用 Java 生成斐波那契数列的方法。 由于斐波那契数列是一个无限数的序列,因此我们使用`BigInteger`类型进行计算。
## Java Fibonacci 经典循环示例
第一种算法使用 for 循环。
`FibonacciLoopEx.java`
```
package com.zetcode;
import java.math.BigInteger;
public class FibonacciLoopEx {
public static BigInteger fibonacci(int n) {
if (n <= 1) return BigInteger.valueOf(n);
BigInteger previous = BigInteger.ZERO, next = BigInteger.ONE, sum;
for (int i = 2; i <= n; i++) {
sum = previous;
previous = next;
next = sum.add(previous);
}
return next;
}
public static void main(String[] args) {
for (int i = 0; i <= 99; i++) {
BigInteger val = fibonacci(i);
System.out.println(val);
}
}
}
```
该示例打印斐波那契数列的前一百个值。
## Java Fibonacci 递归示例
在第二个示例中,我们使用递归算法计算斐波那契数列,其中`fibonacci()`方法调用自身进行计算。
`FibonacciRecursiveEx.java`
```
package com.zetcode;
import java.math.BigInteger;
public class FibonacciRecursiveEx {
public static BigInteger fibonacci(int n) {
if (n == 0 || n == 1) {
return BigInteger.ONE;
}
return fibonacci(n - 2).add(fibonacci(n - 1));
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
System.out.println(fibonacci(i));
}
}
}
```
该示例计算斐波那契序列的前十个值。
## Java 斐波那契流示例
第三个示例使用 Java 8 流进行计算。
`FibonacciStreamEx.java`
```
package com.zetcode;
import java.math.BigInteger;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class FibonacciStreamEx {
public static List<BigInteger> fibonacci(int limit) {
var vals = Stream.iterate(new BigInteger[] { BigInteger.ZERO, BigInteger.ONE },
t -> new BigInteger[] { t[1], t[0].add(t[1]) })
.limit(limit)
.map(n -> n[1])
.collect(Collectors.toList());
return vals;
}
public static void main(String[] args) {
System.out.println(fibonacci(100));
}
}
```
本示例计算值到一定限制。
在本教程中,我们展示了如何以三种不同的方式在 Java 中计算斐波那契数列:经典循环,递归算法和函数方式。
\ No newline at end of file
# Java ProcessBuilder 教程
原文:http://zetcode.com/java/processbuilder/
Java ProcessBuilder 教程显示了如何使用`ProcessBuilder`创建操作系统进程。
## 流程构建器
ProcessBuilder 用于创建操作系统进程。 其`start()`方法创建具有以下属性的新`Process`实例:
* 命令
* 环境
* 工作目录
* 输入来源
* 标准输出和标准错误输出的目标
* redirectErrorStream
## ProcessBuilder 运行程序
`command()`执行程序。 使用`waitFor()`,我们可以等待过程完成。
`ExecuteProgram.java`
```
package com.zetcode;
import java.io.IOException;
public class ExecuteProgram {
public static void main(String[] args) throws IOException, InterruptedException {
var processBuilder = new ProcessBuilder();
processBuilder.command("notepad.exe");
var process = processBuilder.start();
var ret = process.waitFor();
System.out.printf("Program exited with code: %d", ret);
}
}
```
该程序执行 Windows 记事本应用程序。 它返回其退出代码。
## ProcessBuilder 命令输出
以下示例执行命令并显示其输出。
`ProcessBuilderEx.java`
```
package com.zetcode;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class ProcessBuilderEx {
public static void main(String[] args) throws IOException {
var processBuilder = new ProcessBuilder();
processBuilder.command("cal", "2019", "-m 2");
var process = processBuilder.start();
try (var reader = new BufferedReader(
new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
}
}
```
该示例运行 Linux `cal`命令。
```
processBuilder.command("cal", "2019", "-m 2");
```
`command()`执行`cal`程序。 其他参数是程序的选项。 为了在 Windows 机器上运行命令,我们可以使用以下命令:`processBuilder.command("cmd.exe", "/c", "ping -n 3 google.com")`
```
var process = processBuilder.start();
```
`start()`启动了该过程。
```
try (var reader = new BufferedReader(
new InputStreamReader(process.getInputStream()))) {
```
使用`getInputStream()`方法,我们从流程的标准输出中获取输入流。
```
February 2019
Su Mo Tu We Th Fr Sa
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28
```
这是输出。
## ProcessBuilder 重定向输出
使用`redirectOutput()`,我们可以重定向流程构建器的标准输出目的地。
`RedirectOutputEx.java`
```
package com.zetcode;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
public class RedirectOutputEx {
public static void main(String[] args) throws IOException {
var homeDir = System.getProperty("user.home");
var processBuilder = new ProcessBuilder();
processBuilder.command("cmd.exe", "/c", "date /t");
var fileName = new File(String.format("%s/Documents/tmp/output.txt", homeDir));
processBuilder.redirectOutput(fileName);
var process = processBuilder.start();
try (var reader = new BufferedReader(
new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
}
}
```
该程序将构建器的输出重定向到文件。 它运行 Windows `date`命令。
```
processBuilder.redirectOutput(fileName);
```
我们将流程构建器的标准输出重定向到文件。
```
try (var reader = new BufferedReader(
new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
```
现在输出到文件。
```
$ echo %cd%
C:\Users\Jano\Documents\tmp
$ more output.txt
Thu 02/14/2019
```
当前日期已写入`output.txt`文件。
## ProcessBuilder 重定向输入和输出
下一个示例同时重定向输入和输出。
`src/resources/input.txt`
```
sky
blue
steel
morning
coffee
earth
forest
```
这是`input.txt`文件的内容。
`ProcessBuilderRedirectIOEx.java`
```
package com.zetcode;
import java.io.File;
import java.io.IOException;
public class ProcessBuilderRedirectIOEx {
public static void main(String[] args) throws IOException {
var processBuilder = new ProcessBuilder();
processBuilder.command("cat")
.redirectInput(new File("src/resources", "input.txt"))
.redirectOutput(new File("src/resources/", "output.txt"))
.start();
}
}
```
在程序中,我们将输入从`input.txt`文件重定向到`cat`命令,并将命令的输出重定向到`output.txt`文件。
## ProcessBuilder 继承 IO
`inheritIO()`将子流程标准 I / O 的源和目的地设置为与当前 Java 流程相同。
`ProcessBuilderInheritIOEx.java`
```
package com.zetcode;
import java.io.IOException;
public class ProcessBuilderInheritIOEx {
public static void main(String[] args) throws IOException, InterruptedException {
var processBuilder = new ProcessBuilder();
processBuilder.command("cmd.exe", "/c", "dir");
var process = processBuilder.inheritIO().start();
int exitCode = process.waitFor();
System.out.printf("Program ended with exitCode %d", exitCode);
}
}
```
通过继承已执行命令的 IO,我们可以跳过读取步骤。 程序输出项目目录的内容和显示退出代码的消息。
```
02/14/2019 04:55 PM <DIR> .
02/14/2019 04:55 PM <DIR> ..
02/19/2019 01:11 PM <DIR> .idea
02/14/2019 04:55 PM <DIR> out
02/14/2019 04:52 PM 433 ProcessBuilderInheritIOEx.iml
02/14/2019 04:53 PM <DIR> src
1 File(s) 433 bytes
5 Dir(s) 157,350,264,832 bytes free
Program ended with exitCode 0
```
我们同时获得执行的命令和自己的 Java 程序的输出。
## ProcessBuilder 环境
`environment()`方法返回流程构建器环境的字符串映射视图。
`ProcessBuilderEnvEx.java`
```
package com.zetcode;
public class ProcessBuilderEnvEx {
public static void main(String[] args) {
var pb = new ProcessBuilder();
var env = pb.environment();
env.forEach((s, s2) -> {
System.out.printf("%s %s %n", s, s2);
});
System.out.printf("%s %n", env.get("PATH"));
}
}
```
该程序显示所有环境变量。
```
configsetroot C:\WINDOWS\ConfigSetRoot
USERDOMAIN_ROAMINGPROFILE LAPTOP-OBKOFV9J
LOCALAPPDATA C:\Users\Jano\AppData\Local
PROCESSOR_LEVEL 6
USERDOMAIN LAPTOP-OBKOFV9J
LOGONSERVER \\LAPTOP-OBKOFV9J
JAVA_HOME C:\Users\Jano\AppData\Local\Programs\Java\openjdk-11\
SESSIONNAME Console
...
```
这是 Windows 上的示例输出。
在下一个程序中,我们定义一个自定义环境变量。
`ProcessBuilderEnvEx2.java`
```
package com.zetcode;
import java.io.IOException;
public class ProcessBuilderEnvEx2 {
public static void main(String[] args) throws IOException {
var pb = new ProcessBuilder();
var env = pb.environment();
env.put("mode", "development");
pb.command("cmd.exe", "/c", "echo", "%mode%");
pb.inheritIO().start();
}
}
```
该程序定义一个`mode`变量并在 Windows 上输出。
```
pb.command("cmd.exe", "/c", "echo", "%mode%");
```
`%mode%`是 Windows 的环境变量语法; 在 Linux 上,我们使用`$mode`
## ProcessBuilder 目录
`directory()`方法设置流程构建器的工作目录。
`ProcessBuilderDirectoryEx.java`
```
package com.zetcode;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
public class ProcessBuilderDirectoryEx {
public static void main(String[] args) throws IOException {
var homeDir = System.getProperty("user.home");
var pb = new ProcessBuilder();
pb.command("cmd.exe", "/c", "dir");
pb.directory(new File(homeDir));
var process = pb.start();
try (var reader = new BufferedReader(
new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
}
}
```
该示例将主目录设置为流程生成器的当前目录。 我们显示主目录的内容。
```
var homeDir = System.getProperty("user.home");
```
我们得到用户的主目录。
```
pb.command("cmd.exe", "/c", "dir");
```
我们定义了一个在 Windows 上执行`dir`程序的命令。
```
pb.directory(new File(homeDir));
```
我们设置流程构建器的目录。
```
Volume in drive C is Windows
Volume Serial Number is 4415-13BB
Directory of C:\Users\Jano
02/14/2019 11:48 AM <DIR> .
02/14/2019 11:48 AM <DIR> ..
10/13/2018 08:38 AM <DIR> .android
01/31/2019 10:58 PM 281 .bash_history
12/17/2018 03:02 PM <DIR> .config
...
```
这是一个示例输出。
## ProcessBuilder 非阻塞操作
在下面的示例中,我们创建一个异步过程。
`ProcessBuilderNonBlockingEx.java`
```
package com.zetcode;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;
public class ProcessBuilderNonBlockingEx {
public static void main(String[] args) throws InterruptedException,
ExecutionException, TimeoutException, IOException {
var executor = Executors.newSingleThreadExecutor();
var processBuilder = new ProcessBuilder();
processBuilder.command("cmd.exe", "/c", "ping -n 3 google.com");
try {
var process = processBuilder.start();
System.out.println("processing ping command ...");
var task = new ProcessTask(process.getInputStream());
Future<List<String>> future = executor.submit(task);
// non-blocking, doing other tasks
System.out.println("doing task1 ...");
System.out.println("doing task2 ...");
var results = future.get(5, TimeUnit.SECONDS);
for (String res : results) {
System.out.println(res);
}
} finally {
executor.shutdown();
}
}
private static class ProcessTask implements Callable<List<String>> {
private InputStream inputStream;
public ProcessTask(InputStream inputStream) {
this.inputStream = inputStream;
}
@Override
public List<String> call() {
return new BufferedReader(new InputStreamReader(inputStream))
.lines()
.collect(Collectors.toList());
}
}
}
```
该程序创建一个在控制台上运行 ping 命令的进程。 它在`Executors.newSingleThreadExecutor()`方法的帮助下在单独的线程中执行。
```
processing ping command ...
doing task1 ...
doing task2 ...
Pinging google.com [2a00:1450:4001:825::200e] with 32 bytes of data:
Reply from 2a00:1450:4001:825::200e: time=108ms
Reply from 2a00:1450:4001:825::200e: time=111ms
Reply from 2a00:1450:4001:825::200e: time=112ms
Ping statistics for 2a00:1450:4001:825::200e:
Packets: Sent = 3, Received = 3, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 108ms, Maximum = 112ms, Average = 110ms
```
这是输出。
## ProcessBuilder 管道操作
管道是一种用于将信息从一个程序进程传递到另一个程序进程的技术。
`ProcessBuilderPipeEx.java`
```
package com.zetcode;
import java.io.File;
import java.io.IOException;
public class ProcessBuilderPipeEx {
public static void main(String[] args) throws IOException {
var homeDir = System.getProperty("user.home");
var processBuilder = new ProcessBuilder();
processBuilder.command("cmd.exe", "/c", "dir | grep [dD]o");
processBuilder.directory(new File(homeDir));
processBuilder.inheritIO().start();
}
}
```
该示例通过管道(|)将信息从`dir`命令发送到`grep`命令。
```
Volume in drive C is Windows
11/14/2018 06:57 PM <DIR> .dotnet
02/18/2019 10:54 PM <DIR> Documents
02/17/2019 01:11 AM <DIR> Downloads
```
This is the output.
在本教程中,我们使用 Java 的`ProcessBuilder`执行 OS 进程。 您可能也对相关教程感兴趣: [Java Files.walk 教程](/java/fileswalk/)[Java 教程](/lang/java/)
\ No newline at end of file
# Java 11 的新功能
原文:http://zetcode.com/articles/java11/
在本文中,我们介绍了 Java 11 的一些新功能。Java 11 于 25.9 发布。 2018。在本文中,我们将重点介绍 Java 11 的新编程功能。
## Java 11 组织变更
Java 11 做了大量整理工作。 Java EE,CORBA 和 Java FX 已从 JDK 中删除。 它们可以从 Maven 存储库中获得。 JavaScript Nashorn 引擎已被弃用。 Java 小程序已被永久删除。
## 下载 Java 11
我们下载 [OpenJDK](http://jdk.java.net/11)[Oracle JDK](https://www.oracle.com/technetwork/java/javase/downloads/jdk11-downloads-5066655.html)
IntelliJ IDEA 2018.2.4 社区版已支持 Java 11。
```
$ ~/bin/jdk-11/bin/java --version
openjdk 11 2018-09-25
OpenJDK Runtime Environment 18.9 (build 11+28)
OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)
```
在我们的示例中,我们使用了 OpenJDK。
## Java 11-启动单文件源文件
无需使用`javac`即可在不进行事先编译的情况下启动单文件 Java 源文件。 这有助于新的程序员学习 Java 的基础知识,并促进创建更简单的程序。
我们不会用字节码文件来弄乱我们的空间,也不需要担心 Java 打包规则。
`SimpleEx.java`
```
package com.zetcode;
public class SimpleEx {
public static void main(String[] args) {
System.out.println("Java 11 example");
}
}
```
这是一个简单的 Java 源文件。 请注意,该文件不必位于`com/zetcode`子目录中。
```
$ ~/bin/jdk-11/bin/java SimpleEx.java
Java 11 example
```
我们使用`java`工具启动该程序。
## HttpClient 标准化
新的 HttpClient 已标准化。 它位于`java.net.http`程序包中。
`HttpClientEx.java`
```
package com.zetcode;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class HttpClientEx {
public static void main(String[] args) {
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
.uri(URI.create("http://webcode.me"))
.build();
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
}
}
```
在示例中,我们创建一个新的 http 客户端。 然后,我们向 webcode.me 网站生成一个异步 HTTP 请求。
```
$ ~/bin/jdk-11/bin/java HttpClientEx.java
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>My html page</title>
</head>
<body>
<p>
Today is a beautiful day. We go swimming and fishing.
</p>
<p>
Hello there. How are you?
</p>
</body>
</html>
```
服务器以该 HTTP 文件响应。
## Java 11 新的字符串方法
Java 11 中有新的`String`方法。
`StringMethodsEx.java`
```
package com.zetcode;
public class StringMethodsEx {
public static void main(String[] args) {
var word = "falcon ";
System.out.println(word.repeat(5));
var word2 = "\tnice blue\t";
System.out.println(word2 + "sky");
System.out.println(word2.stripTrailing() + "sky");
System.out.println(word2.stripLeading() + "sky");
System.out.println(word2.strip() + "sky");
var word3 = " ";
System.out.println(word3.isEmpty());
System.out.println(word3.isBlank());
var words = "falcon\neagle\nsky\nwood\nforest";
words.lines().forEach(System.out::println);
}
}
```
在示例中,我们演示了新`String`方法的用法。
```
System.out.println(word.repeat(5));
```
`repeat()`方法返回重复 n 次的字符串。
```
System.out.println(word2.stripTrailing() + "sky");
System.out.println(word2.stripLeading() + "sky");
System.out.println(word2.strip() + "sky");
```
`stringTailing()`方法返回删除了所有尾随空格的字符串。 `stringTailing()`方法返回删除了所有前导空格的字符串。 `stringTailing()`方法返回删除了所有前导和尾随空格的字符串。
```
System.out.println(word3.isBlank());
```
如果字符串为空或仅包含空格,则`isBlank()`返回 true。
```
words.lines().forEach(System.out::println);
```
`lines()`方法返回从字符串中提取的行流,以行终止符分隔。
```
$ ~/bin/jdk-11/bin/java StringMethodsEx.java
falcon falcon falcon falcon falcon
nice blue sky
nice bluesky
nice blue sky
nice bluesky
false
true
falcon
eagle
sky
wood
forest
```
这是输出。
## asMatchPredicate 方法
有一个新的`asMatchPredicate`方法可用于正则表达式。
`AsMatchPredicateEx.java`
```
package com.zetcode;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class AsMatchPredicateEx {
public static void main(String[] args) {
var words = Arrays.asList("dog", "Dog", "DOG", "Doggy");
var pred = Pattern.compile("dog",
Pattern.CASE_INSENSITIVE).asMatchPredicate();
words.forEach((word) -> {
if (pred.test(word)) {
System.out.printf("%s matches%n", word);
} else {
System.out.printf("%s does not match%n", word);
}
});
}
}
```
`asMatchPredicate()`方法从编译的模式创建一个新的谓词。 在谓词上,我们称为`test()`方法。
```
$ ~/bin/jdk-11/bin/java AsMatchPredicateEx.java
dog matches
Dog matches
DOG matches
Doggy does not match
```
This is the output.
## 文件 readString 和 writeString
`readString()`方法将文件中的所有内容读取为字符串,`writeString()`方法将`CharSequence`写入文件。
`WriteStringEx.java`
```
package com.zetcode;
import java.nio.file.Path;
import java.nio.file.Files;
import java.io.IOException;
public class WriteStringEx {
public static void main(String[] args) throws IOException {
var words = "forest\nwood\nsky\nrock";
Files.writeString(Path.of("words.txt"), words);
}
}
```
在此示例中,我们将四个单词写入`words.txt`文件。
`ReadStringEx.java`
```
package com.zetcode;
import java.nio.file.Path;
import java.nio.file.Files;
import java.io.IOException;
public class ReadStringEx {
public static void main(String[] args) throws IOException {
var fileName = "words.txt";
var data = Files.readString(Path.of("words.txt"));
System.out.println(data);
}
}
```
在此示例中,我们读取`words.txt`文件的内容并将其写入控制台。
```
$ ~/bin/jdk-11/bin/java ReadStringEx.java
forest
wood
sky
rock
```
This is the output.
在本教程中,我们研究了 Java 11 的新编程功能。
您可能也对以下相关教程感兴趣: [Java 教程](/lang/java/)[Java 流过滤器教程](http://zetcode.com/java/streamfilter/)
\ No newline at end of file
# Java 控制流程
原文:http://zetcode.com/lang/java/flow/
在 Java 教程的这一部分中,我们将讨论程序流控制。 我们将使用几个关键字来使我们能够控制 Java 程序的流程。
## Java 控制流语句
在 Java 语言中,有几个关键字用于更改程序的流程。 语句可以多次执行,也可以仅在特定条件下执行。 `if``else``switch`语句用于测试条件,`while``for`语句用于创建循环,而`break``continue`语句用于更改循环。
当程序运行时,语句从源文件的顶部到底部执行。 逐一。
## Java if 语句
`if`语句具有以下一般形式:
```
if (expression) {
statement;
}
```
`if`关键字用于检查表达式是否为真。 如果为 true,则执行一条语句。 该语句可以是单个语句或复合语句。 复合语句由一个块包围的多个语句组成。 块是用大括号括起来的代码。 如果主体中只有一个语句,则括号是可选的。
`IfStatement.java`
```
package com.zetcode;
import java.util.Random;
public class IfStatement {
public static void main(String[] args) {
Random r = new Random();
int num = r.nextInt();
if (num > 0) {
System.out.println("The number is positive");
}
}
}
```
生成一个随机数。 如果数字大于零,我们将向终端打印一条消息。
```
Random r = new Random();
int num = r.nextInt();
```
这两行生成一个随机整数。 该数字可以是正数或负数。
```
if (num > 0) {
System.out.println("The number is positive");
}
```
使用`if`关键字,我们检查生成的数字是否大于零。 `if`关键字后跟一对圆括号。 在方括号内,我们放置一个表达式。 该表达式产生布尔值。 如果布尔值是 true,则执行两个大括号括起来的块。 在我们的例子中,字符串“ The number is positive”被打印到终端上。 如果随机值为负,则不执行任何操作。 如果我们只有一个表达式,则大括号是可选的。
## Java else 关键字
我们可以使用`else`关键字来创建一个简单的分支。 如果`if`关键字后方括号内的表达式的值为假,则将自动执行`else`关键字后方的语句。
`Branch.java`
```
package com.zetcode;
import java.util.Random;
public class Branch {
public static void main(String[] args) {
Random r = new Random();
int num = r.nextInt();
if (num > 0) {
System.out.println("The number is positive");
} else {
System.out.println("The number is negative");
}
}
}
```
`if`关键字后面的块或`else`关键字后面的块都被执行。
```
if (num > 0) {
System.out.println("The number is positive");
} else {
System.out.println("The number is negative");
}
```
`else`关键字紧随`if`块的右大括号。 它有自己的块,用大括号括起来。
```
$ java com.zetcode.Branch
The number is positive
$ java com.zetcode.Branch
The number is negative
$ java com.zetcode.Branch
The number is negative
```
我们运行该示例三次。 这是一个示例输出。
## 具有 if 的多个分支
我们可以使用`else if`关键字创建多个分支。 仅当不满足先前条件时,`else if`关键字才会测试其他条件。 请注意,我们可以在测试中使用多个`else if`关键字。
以前的程序有一个小问题。 负值设为零。 以下程序将解决此问题。
`MultipleBranches.java`
```
package com.zetcode;
import java.util.Scanner;
public class MultipleBranches {
public static void main(String[] args) {
System.out.print("Enter an integer:");
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
if (num < 0) {
System.out.println("The integer is negative");
} else if (num == 0) {
System.out.println("The integer equals to zero");
} else {
System.out.println("The integer is positive");
}
}
}
```
我们从用户那里收到一个测试值,如果它是负数或正数,或者等于零。
```
System.out.print("Enter an integer:");
```
输入整数的提示将写入标准输出。
```
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
```
使用`java.util`包的`Scanner`类,我们从标准输入中读取一个整数值。
```
if (num < 0) {
System.out.println("The integer is negative");
} else if (num == 0) {
System.out.println("The integer equals to zero");
} else {
System.out.println("The integer is positive");
}
```
如果第一个条件的计算结果为 true,例如 输入的值小于零,将执行第一个程序段,并跳过其余两个程序段。 如果不满足第一个条件,则检查`if else`关键字之后的第二个条件。 如果第二个条件的值为真,则执行第二个块。 如果不是,则执行`else`关键字之后的第三个程序段。 如果不满足先前的条件,则始终执行`else`块。
```
$ java com.zetcode.MultipleBranches
Enter an integer:4
The integer is positive
$ java com.zetcode.MultipleBranches
Enter an integer:0
The integer equals to zero
$ java com.zetcode.MultipleBranches
Enter an integer:-3
The integer is negative
```
我们将示例运行三次,以便测试所有条件。 零被正确处理。
## Java switch 语句
`switch`语句是选择控制流语句。 它允许变量或表达式的值通过多路分支控制程序执行的流程。 与使用`if``else if`语句的组合相比,它以更简单的方式创建多个分支。 每个分支以`break`关键字结尾。
我们使用变量或表达式。 `switch`关键字用于根据值列表测试变量或表达式中的值。 值列表用`case`关键字显示。 如果值匹配,则执行`case`之后的语句。 有一个可选的`default`语句。 如果找不到其他匹配项,则执行该命令。
`SwitchStatement.java`
```
package com.zetcode;
import java.util.Scanner;
public class SwitchStatement {
public static void main(String[] args) {
System.out.print("Enter a domain:");
Scanner sc = new Scanner(System.in);
String domain = sc.nextLine();
domain = domain.trim().toLowerCase();
switch (domain) {
case "us":
System.out.println("United States");
break;
case "de":
System.out.println("Germany");
break;
case "sk":
System.out.println("Slovakia");
break;
case "hu":
System.out.println("Hungary");
break;
default:
System.out.println("Unknown");
break;
}
}
}
```
要求用户输入域名。 读取域名并将其存储在变量中。 该变量使用`switch`关键字针对选项列表进行测试。 在我们的程序中,我们有一个域变量。 我们从命令行读取变量的值。 我们使用`case`语句测试变量的值。 有几种选择。 例如,如果该值等于“ us”,则将“ United States”字符串打印到控制台。
```
Scanner sc = new Scanner(System.in);
String domain = sc.nextLine();
```
从控制台读取用户输入。
```
domain = domain.trim().toLowerCase();
```
`trim()`方法从潜在的前导和尾随空白中剥离变量。 `toLowerCase()`将字符转换为小写。 现在,“ us”,“ US”或“ us”是美国域名的可行选项。
```
switch (domain) {
...
}
```
在圆括号中,`switch`关键字采用将要测试的输入。 输入可以是`byte``short``char``int``enum``String`数据类型。 `switch`关键字的主体放在一对或大括号内。 在体内,我们可以放置多个`case`选项。 每个选项都以`break`关键字结尾。
```
case "us":
System.out.println("United States");
break;
```
在这种情况下,我们测试域变量是否等于“ us”字符串。 如果为 true,则将消息打印到控制台。 该选项以`break`关键字结束。 如果成功评估了其中一个选项,则`break`关键字将终止`switch`块。
```
default:
System.out.println("Unknown");
break;
```
`default`关键字是可选的。 如果没有评估`case`选项,则执行`default`部分。
```
$ java com.zetcode.SwitchStatement
Enter a domain:us
United States
```
这是一个示例输出。
## Java while 语句
`while`语句是一个控制流语句,它允许根据给定的布尔条件重复执行代码。
这是`while`循环的一般形式:
```
while (expression) {
statement;
}
```
`while`关键字在大括号括起来的块内执行语句。 每次将表达式评估为 true 时都会执行这些语句。
`WhileStatement.java`
```
package com.zetcode;
public class WhileStatement {
public static void main(String[] args) {
int i = 0;
int sum = 0;
while (i < 10) {
i++;
sum += i;
}
System.out.println(sum);
}
}
```
在代码示例中,我们从一系列数字计算值的总和。
`while`循环包含三个部分:初始化,测试和更新。 语句的每次执行都称为循环。
```
int i = 0;
```
我们启动 i 变量。 它用作计数器。
```
while (i < 10) {
...
}
```
`while`关键字后的圆括号内的表达式是第二阶段,即测试。 执行主体中的语句,直到表达式的计算结果为 false。
```
i++;
```
`while`循环的最后阶段是更新。 我们增加计数器。 请注意,对`while`循环的不正确处理可能会导致循环不断。
```
$ java com.zetcode.WhileStatement
55
```
程序计算出 0、1,...,9 个值的总和。
`while`语句有一个修改的版本。 这是`do while`语句。 即使不满足条件,也可以保证块内的语句至少运行一次。
`DoWhile.java`
```
package com.zetcode;
public class DoWhile {
public static void main(String[] args) {
int count = 0;
do {
System.out.println(count);
} while (count != 0);
}
}
```
首先执行该块,然后评估真值表达式。 在我们的情况下,条件不满足,`do while`语句终止。
## Java for 语句
如果在启动循环之前知道周期数,则可以使用`for`语句。 在此构造中,我们声明一个计数器变量,该变量在每次循环重复期间都会自动增加或减少值。
`ForStatement.java`
```
package com.zetcode;
public class ForStatement {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
}
}
```
在此示例中,我们将数字 0..9 打印到控制台。
```
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
```
for 循环分为三个阶段。 首先,我们将计数器`i`初始化为零。 此阶段仅完成一次。 接下来是条件。 如果满足条件,则执行 for 块中的语句。 然后进入第三阶段:计数器增加。 现在我们重复 2 和 3 个阶段,直到不满足条件并终止 for 循环。 在我们的情况下,当计数器`i`等于 10 时,for 循环停止执行。
for 循环可用于轻松遍历数组。 从数组的`length`属性,我们知道数组的大小。
`ForStatement2.java`
```
package com.zetcode;
public class ForStatement2 {
public static void main(String[] args) {
String[] planets = {"Mercury", "Venus", "Earth",
"Mars", "Jupiter", "Saturn", "Uranus", "Pluto"};
for (int i = 0; i < planets.length; i++) {
System.out.println(planets[i]);
}
System.out.println("In reverse:");
for (int i = planets.length - 1; i >= 0; i--) {
System.out.println(planets[i]);
}
}
}
```
我们有一个数组,用于保存太阳系中行星的名称。 使用两个 for 循环,我们按升序和降序打印值。
```
for (int i = 0; i < planets.length; i++) {
System.out.println(planets[i]);
}
```
通过从零开始的索引访问数组。 第一项的索引为 0。因此,`i`变量被初始化为零。 条件检查`i`变量是否小于数组的长度。 在最后阶段,`i`变量增加。
```
for (int i = planets.length - 1; i >= 0; i--) {
System.out.println(planets[i]);
}
```
此 for 循环以相反顺序打印数组的元素。 `i`计数器被初始化为数组大小。 由于索引基于零,因此最后一个元素的索引数组大小为 1。 该条件确保计数器大于或等于零。 (数组索引不能为负数)。 在第三步中,`i`计数器递减 1。
可以在 for 循环的初始化和迭代阶段中放置更多表达式。
`ForStatement3.java`
```
package com.zetcode;
import java.util.Arrays;
import java.util.Random;
public class ForStatement3 {
public static void main(String[] args) {
Random r = new Random();
int[] values = new int[10];
int num;
int sum=0;
for (int i = 0; i < 10; i++, sum += num) {
num = r.nextInt(10);
values[i] = num;
}
System.out.println(Arrays.toString(values));
System.out.println("The sum of the values is " + sum);
}
}
```
在我们的示例中,我们创建了一个十个随机数的数组。 计算这些数字的总和。
```
for (int i = 0; i < 10; i++, sum += num) {
num = r.nextInt(10);
values[i] = num;
}
```
在 for 循环的第三部分中,我们有两个用逗号分隔的表达式。 `i`计数器增加,并且当前编号添加到`sum`变量中。
```
$ java com.zetcode.ForStatement3
[1, 9, 2, 9, 0, 9, 8, 5, 5, 3]
The sum of the values is 51
```
这是程序的示例执行。
## Java 增强的语句
增强的`for`语句简化了遍历数据集合的过程。 它没有明确的计数器。 该语句一一遍历数组或集合,并将当前值复制到构造中定义的变量中。
`EnhancedFor.java`
```
package com.zetcode;
public class EnhancedFor {
public static void main(String[] args) {
String[] planets = {
"Mercury", "Venus", "Earth",
"Mars", "Jupiter", "Saturn", "Uranus", "Pluto"
};
for (String planet : planets) {
System.out.println(planet);
}
}
}
```
在此示例中,我们使用增强的`for`语句遍历一系列行星。
```
for (String planet : planets) {
System.out.println(planet);
}
```
`for`语句的用法很简单。 行星是我们迭代经过的阵列。 `planet`是具有数组中当前值的临时变量。 `for`语句遍历所有行星并将它们打印到控制台。
```
$ java com.zetcode.EnhancedFor
Mercury
Venus
Earth
Mars
Jupiter
Saturn
Uranus
Pluto
```
运行上面的 Java 程序将给出此输出。
## Java Break 语句
`break`语句可用于终止由`while``for``switch`语句定义的块。
`BreakStatement.java`
```
package com.zetcode;
import java.util.Random;
public class BreakStatement {
public static void main(String[] args) {
Random random = new Random();
while (true) {
int num = random.nextInt(30);
System.out.print(num + " ");
if (num == 22) {
break;
}
}
System.out.print('\n');
}
}
```
我们定义了一个无限的`while`循环。 我们使用`break`语句退出此循环。 我们从 1 到 30 中选择一个随机值并打印出来。 如果该值等于 22,则结束无穷的 while 循环。
```
while (true) {
...
}
```
在 while 语句的括号内放置 true 会创建一个无限循环。 我们必须自己终止循环。 请注意,这样的代码容易出错。 我们应该小心使用这样的循环。
```
if (num == 22) {
break;
}
```
当随机选择的值等于 22 时,将执行`break`语句,并终止`while`循环。
```
$ java com.zetcode.BreakStatement
23 12 0 4 13 16 6 12 11 9 24 23 23 19 15 26 3 3 27 28 25 3 3 25 6 22
$ java com.zetcode.BreakStatement
23 19 29 27 3 28 2 2 26 0 0 24 17 4 7 12 8 20 22
$ java com.zetcode.BreakStatement
15 20 10 25 2 19 26 4 13 21 15 21 21 24 3 22
```
在这里,我们看到了该程序的三个示例执行。
## Java 继续声明
`continue`语句用于跳过循环的一部分,并继续循环的下一个迭代。 它可以与`for``while`语句结合使用。
在下面的示例中,我们将打印一个数字列表,这些数字不能除以 2 而没有余数。
`ContinueStatement.java`
```
package com.zetcode;
public class ContinueStatement {
public static void main(String[] args) {
int num = 0;
while (num < 100) {
num++;
if ((num % 2) == 0) {
continue;
}
System.out.print(num + " ");
}
System.out.print('\n');
}
}
```
我们使用`while`循环遍历数字 1..99。
```
if ((num % 2) == 0) {
continue;
}
```
如果表达式`num % 2`返回 0,则可以将所讨论的数字除以 2。执行`continue`语句,并跳过循环的其余部分。 在我们的例子中,循环的最后一条语句将被跳过,并且数字不会输出到控制台。 下一个迭代开始。
在 Java 教程的这一部分中,我们正在讨论控制流结构。 我们已经介绍了`if``if else``else``while``switch``for``break``continue`语句。
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
# Java 包
原文:http://zetcode.com/lang/java/packages/
在 Java 教程的这一部分中,我们将讨论 Java 包。
程序包是一组相关类型的组合,提供访问保护和名称空间管理。 Java 中的包与 C#中的名称空间类似。
## 使用 Java 创建软件包
使用`package`关键字声明包。 该语句必须放在每个源文件的顶部。 每个源文件中只能有一个这样的语句。 Java 源文件必须放在与软件包名称匹配的目录中。
```
package com.zetcode;
```
使用上述软件包的文件中定义的所有类型都是`com.zetcode`软件包的一部分。 类`Being`具有完全限定的名称`com.zetcode.Being`。 全球有数百万的 Java 程序员。 为避免潜在的名称冲突,Java 中有一个命名约定。 程序包名称使用反向 Internet 域名。 字母以小写字母书写。 只能有一个`zetcode.com`域名,因此对于软件包使用反向名称`com.zetcode`将使它们唯一。 带有`com.zetcode`包的 Java 源文件必须位于`com/zetcode`子目录中。 包名称以小写形式编写,以避免与类或接口的名称冲突。
`import`关键字在源文件的开头用于指定类型(类,接口,枚举或批注)或以后要引用的整个 Java 包,而不在引用中包含它们的包名称。 从 Java SE 5.0 开始,import 语句可以导入类的静态成员(方法和变量)。
```
import java.awt.*;
```
使用*通配符,我们可以一次导入整个包。 导入后,我们可以引用所有`java.awt`包类型,而无需使用其全限定名。
```
import java.awt.event.*;
```
`java.awt.event`子包未随`java.awt.*`导入一起导入。 子包必须独立导入。
```
import java.util.Random;
```
在这种情况下,仅导入`Random`类。 现在可以使用其简单的类名来引用`Random`类。
## Java 8 中的核心软件包
以下是 Java 8 中的核心软件包的列表:
* java.lang —基本语言功能和基本类型
* java.util —收集数据结构类
* java.io-用于文件操作的 Java API
* java.math —多精度算术
* java.nio — Java 的非阻塞 I / O 框架
* java.net —网络操作,套接字,DNS 查找,...
* java.security —密钥生成,加密和解密
* java.sql —用于访问数据库的 Java 数据库连接(JDBC)
* java.awt —本机 GUI 组件的基本软件包层次结构
* javax.swing —与平台无关的丰富 GUI 组件的包层次结构
* java.applet-用于创建小程序的类
* java.beans-包含与开发 bean 有关的类-基于 JavaBean 体系结构的组件。
* java.text —提供用于以独立于自然语言的方式处理文本,日期,数字和消息的类和接口。
* java.rmi —用于远程方法调用的 Java API。
* java.time —日期,时间,瞬间和持续时间的主要 API。
`java.lang`程序包不使用导入语句即可使用。
## 实际例子
以下示例显示了如何创建包和导入类型。
`Packages.java`
```
package com.zetcode;
import java.util.Random;
public class Packages {
public static void main(String[] args) {
Random r = new Random();
int x = r.nextInt();
System.out.println(x);
java.util.Calendar c = java.util.Calendar.getInstance();
System.out.println(c.getTime());
}
}
```
该示例使用两种类型:`Random`类和`Calendar`类。 第一类是导入的,第二类是由其完全限定的名称引用的。
```
package com.zetcode;
```
我们用`package`关键字声明一个包。 `Packages.java`文件必须位于`com/zetcode`子目录中。
```
import java.util.Random;
```
此代码行使我们可以使用不带包名称的`Random`类。
```
Random r = new Random();
```
在这里,我们使用`Random`而不使用其全名。
```
java.util.Calendar c = java.util.Calendar.getInstance();
```
如果我们没有在类型上使用`import`关键字,则在本例中只能使用其全名-`java.util.Calendar`来引用它。 `import`关键字可以节省很多打字时间。
```
$ ls com/zetcode/
Packages.java
```
`Packages.java`源文件位于`com/zetcode`子目录中。 程序包名称必须反映目录结构。
```
$ javac com/zetcode/Packages.java
```
我们使用`javac`工具编译源文件。 该工具从`com/zetcode`目录的父目录中调用。
```
$ java com.zetcode.Packages
179489124
Thu Jan 19 20:53:08 CET 2017
```
这是`com.zetcode.Packages`程序的输出。
## Java 包专用可见性
如果我们未指定任何访问修饰符(例如`private``protected``public`),那么我们将获得包私有的可见性。 在这种情况下,变量和方法可在同一包中访问。 其他程序包中的类无法访问通过程序包私有访问声明的类和成员。
## Java 默认包
如果未声明任何包,则该文件中定义的所有类型都是默认未命名包的一部分。 建议始终将您的类型放在包装中。 即使是小型程序。
`DefaultPackage.java`
```
public class DefaultPackage {
public static void main(String[] args) {
System.out.println("A class in a default package");
}
}
```
`DefaultPackage`类是默认软件包的一部分。
```
$ ls
DefaultPackage.java
```
如果未指定包,则不会将源文件放置在特定的子目录中。
```
$ javac DefaultPackage.java
$ java DefaultPackage
A class in a default package
```
我们编译代码并运行应用程序。 源文件和字节码位于当前工作目录中。
## Java 自动导入
Java 编译器自动导入两个软件包:`java.lang`和当前软件包。
`Constants.java`
```
package com.zetcode;
public class Constants {
public static final String version = "1.0";
}
```
`Constants`类与引用其版本成员的`AutomaticImports`位于同一包中。
`AutomaticImports.java`
```
package com.zetcode;
public class AutomaticImports {
public static void main(String[] args) {
String os = System.getProperty("os.name");
System.out.println(os);
System.out.println(Constants.version);
}
}
```
在此示例中,我们引用了 Java 编译器自动导入的一些类。
```
String os = System.getProperty("os.name");
```
`String``System`类是`java.lang`程序包的一部分。
```
System.out.println(Constants.version);
```
`Constants`类与`AutomaticImports`类位于同一包中。 因此,我们可以访问类及其成员,而无需使用完全限定的名称或使用`import`关键字。
```
$ ls com/zetcode/
AutomaticImports.java Constants.java
```
`AutomaticImports.java``Constants.java`文件都位于同一子目录中。
```
$ javac com/zetcode/AutomaticImports.java com/zetcode/Constants.java
```
这两个文件都被编译。
```
$ java com.zetcode.AutomaticImports
Linux
1.0
```
这是`com.zetcode.AutomaticImports`程序的示例输出。
## Java 静态导入
如果我们经常使用一些静态成员,则可以稍后使用`import static`语句来引用它们,而无需使用完整的类名。 静态导入应谨慎使用。
`StaticImport.java`
```
package com.zetcode;
import static java.lang.Math.E;
import static java.lang.Math.PI;
import static java.lang.Math.abs;
public class StaticImport {
public static void main(String[] args) {
System.out.println(E);
System.out.println(PI);
System.out.println(abs(-5));
}
}
```
在此示例中,我们引用两个常量和一个静态方法。
```
import static java.lang.Math.E;
import static java.lang.Math.PI;
import static java.lang.Math.abs;
```
我们使用`import static`语句启用不带全名的引用。
```
System.out.println(E);
System.out.println(PI);
System.out.println(abs(-5));
```
我们引用这三个成员时没有其类名。
```
$ java com.zetcode.StaticImport
2.718281828459045
3.141592653589793
5
```
这是`com.zetcode.StaticImport`程序的输出。
本章介绍了 Java 中的软件包。 我们已经展示了如何在包中组织代码。
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
# Java 教程
原文:http://zetcode.com/lang/java/
这是一个 Java 教程。 它是使用 OpenJDK 13 创建的。在本教程中,您将学习 Java 语言。 本教程适合初学者。
## 目录
<nav>
* [Java 语言](java/)
* [词法结构](lexis/)
* [基础知识](basics/)
* [数据类型](datatypes/)
* [数据类型 II](datatypes2/)
* [字符串](strings/)
* [数组](arrays/)
* [表达式](expressions/)
* [流量控制](flow/)
* [OOP](oop/)
* [方法](methods/)
* [OOP II](oop2/)
* [软件包](packages/)
* [例外](exceptions/)
* [集合](collections/)
* [](streams/)
</nav>
## 爪哇
Java 是一种现代的,高级的,通用的,面向对象的编程语言。 该语言的设计目标是软件健壮性,耐用性和程序员生产率。 它可用于在 PC 或嵌入式系统上创建控制台应用程序,GUI 应用程序,Web 应用程序。
## 相关教程和电子书
C#与 Java 类似。 [C#教程](/lang/csharp/)中介绍了 C#。 [Jetty 教程](/java/jetty/)涵盖了 Jetty Servlet 容器和 Web 服务器。 [Android 教程](/mob/android/)涵盖了 Java 中的 Android 开发。 Java GUI 编程在 [JavaFX 教程](/gui/javafx/)[高级 Java Swing 电子书](/ebooks/advancedjavaswing/)[Java Swing 教程](/tutorials/javaswingtutorial/)[Java 2D 教程](/gfx/java2d/)中进行了介绍。 [Java 2D 游戏教程](/tutorials/javagamestutorial/)讲授 Java 游戏编程。 [MySQL Java 教程](/db/mysqljava/)[PostgreSQL Java 教程](/db/postgresqljavatutorial/)[MongoDB Java 教程](/db/mongodbjava/)涵盖了 Java 中的数据库编程。
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
# Java Files.list 教程
原文:http://zetcode.com/java/fileslist/
Java Files.list 教程显示了如何使用`Files.list`列出 Java 中的文件。
`Files.list`返回目录元素的延迟填充流。 该列表不是递归的。
流的元素是`Path`对象。
## Files.list 当前目录
第一个示例列出了当前目录。
`FilesListEx.java`
```
package com.zetcode;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class FilesListEx {
public static void main(String[] args) throws IOException {
Files.list(Paths.get("."))
.forEach(path -> System.out.println(path));
}
}
```
点号代表当前的工作目录。 我们使用`Paths.get()`获得路径对象。
## Files.list 目录
以下示例列出了用户主目录中的目录。
`FilesListEx2.java`
```
package com.zetcode;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
public class FilesListEx2 {
public static void main(String[] args) throws IOException {
var homeDir = System.getProperty("user.home");
Files.list(new File(homeDir).toPath())
.filter(path -> path.toFile().isDirectory())
.forEach(System.out::println);
}
}
```
我们使用`toFile()`将路径对象转换为`File`并调用`isDirectory()`方法。 用`filter()`过滤流。
## Files.list 按文件扩展名
下一个程序列出了所有 PDF 文件。
`FilesListEx3.java`
```
package com.zetcode;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class FilesListEx3 {
public static void main(String[] args) throws IOException {
var homeDir = System.getProperty("user.home")
+ System.getProperty("file.separator") + "Downloads";
Files.list(Paths.get(homeDir)).filter(path -> path.toString().endsWith(".pdf"))
.forEach(System.out::println);
}
}
```
该程序将在 Downloads 目录中列出 PDF 文件。 路径对象被转换为字符串,我们在字符串上调用`endsWith()`以检查其是否以`pdf`扩展名结尾。
## Files.list 计数文件
我们计算 PDF 文件的数量。
`FilesListEx4.java`
```
package com.zetcode;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class FilesListEx4 {
public static void main(String[] args) throws IOException {
var homeDir = System.getProperty("user.home")
+ System.getProperty("file.separator") + "Downloads";
var nOfPdfFiles = Files.list(Paths.get(homeDir)).filter(path -> path.toString()
.endsWith(".pdf")).count();
System.out.printf("There are %d PDF files", nOfPdfFiles);
}
}
```
文件数由`count()`确定。
在本教程中,我们使用`Files.list`列出目录内容。 您可能也对相关教程感兴趣: [Java 文件教程](/java/file/)[Java Files.walk 教程](/java/fileswalk/)[Java Files.list 教程](/java/fileslist/)[Java DirectoryStream 教程](/java/directorystream/)[Java 创建目录](/java/createdirectory/)[用 Java 复制文件](/java/copyfile/)[Java Unix 时间](/java/unixtime/)[用 Java 创建文件](/java/createfile/)[Java 教程](/lang/java/)[阅读 Java](/articles/javareadtext/) 中的文本文件。
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
# 码头教程
原文:http://zetcode.com/java/jetty/
这是 Jetty 教程。 这是一个初学者教程,致力于进行一些基本的 Jetty 编程和管理。
## 目录
<nav>
* [简介](introduction/)
* [基本管理](admin/)
* [嵌入式码头](embedded/)
* [Servlet 和 Java 服务器页面](servlets/)
* [正在记录](logging/)
* [HttpClient](httpclient/)
* [FastCGI](fastcgi/)
* [WebSocket](websocket/)
* [在 Linux 服务器](install/)上安装 Jetty
</nav>
## 码头
Jetty 是一个 Servlet 容器和 Web 服务器。 它可以作为独立服务器运行,也可以以嵌入式模式运行。 该项目是在 Eclipse Foundation 下开发的。
## 相关教程
[嵌入式 Tomcat 教程](/web/embeddedtomcat)显示了如何在嵌入式模式下使用 Tomcat。 [Java 教程](/lang/java/)描述了 Java 编程语言。 [MongoDB Java 教程](/db/mongodbjava/)涵盖了 Java 中的 MongoDB 编程。
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册