Nous continuons l' histoire des API qui sont apparues dans les nouvelles versions de Java.
1. Files.mismatch()
Apparu dans: Java 12
En pratique, il est souvent nécessaire de vérifier si deux fichiers sont exactement identiques ou non. En utilisant la méthode Files.mismatch()
introduite dans Java 12, cela peut enfin être fait. Cette méthode renvoie la position du premier octet de non-concordance dans deux fichiers, ou -1
si les fichiers sont identiques.
Cela peut être utile, par exemple, lorsque vous synchronisez le contenu de deux répertoires. Afin de ne pas écraser le fichier lors de la copie avec le même contenu et de ne pas charger à nouveau le disque, vous pouvez d'abord vérifier si les fichiers sont identiques ou non:
public static void syncDirs(Path srcDir, Path dstDir)
throws IOException {
try (Stream<Path> stream = Files.list(srcDir)) {
for (Path src : stream.collect(toList())) {
Path dst = dstDir.resolve(src.getFileName());
if (!Files.exists(dst)) {
System.out.println("Copying file " + dst);
Files.copy(src, dst);
} else if (Files.mismatch(src, dst) >= 0) {
System.out.println("Overwriting file " + dst);
Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING);
}
}
}
}
(Au fait, quand vont-ils finalement Stream
hériter Iterable
? Je veux juste écrire for (Path file : stream)
, et ne pas jouer avec les listes intermédiaires.)
2. Nouvelles méthodes java.time
Introduit dans: Java 9
Depuis près de 20 ans, Java n'a pas eu d'API normale pour travailler avec les dates et les heures. Ce problème n'a été résolu que dans Java 8 lorsqu'ils ont introduit un nouveau package java.time
sous la direction du célèbre Stephen Colborn , créateur de la bibliothèque Joda Time . Et dans la neuvième version java.time
, de nombreuses méthodes intéressantes ont été ajoutées.
Java 8 Duration
(, 2 , 7 , 15 , 12 ). Java 9 toDaysPart()
, toHoursPart()
, toMinutesPart()
, toSecondsPart()
.. :
public static String modifiedAgo(Path path) throws IOException {
FileTime time = Files.getLastModifiedTime(path);
Instant to = Instant.now();
Instant from = time.toInstant();
Duration d = Duration.between(from, to);
return String.format(
" %d , %d , %d , %d ",
d.toDaysPart(), d.toHoursPart(),
d.toMinutesPart(), d.toSecondsPart());
}
, ? Java 8, , . Java 9 Duration.dividedBy()
:
public static long modifiedAgo(Path path, ChronoUnit unit)
throws IOException {
FileTime time = Files.getLastModifiedTime(path);
Instant to = Instant.now();
Instant from = time.toInstant();
Duration d = Duration.between(from, to);
return d.dividedBy(unit.getDuration());
}
public static void main(String[] args) throws Exception {
Path path = ...
System.out.printf(" %d %n",
modifiedAgo(path, ChronoUnit.MONTHS));
}
LocalDate
. LocalDate.ofInstant()
Instant
LocalDate
:
LocalDate date = LocalDate.ofInstant(
Instant.now(), ZoneId.systemDefault());
System.out.println(date);
LocalDate.datesUntil()
, - Stream
:
LocalDate from = LocalDate.of(2020, 1, 1);
LocalDate to = LocalDate.of(2020, 1, 9);
from.datesUntil(to)
.forEach(System.out::println);
:
2020-01-01
2020-01-02
2020-01-03
2020-01-04
2020-01-05
2020-01-06
2020-01-07
2020-01-08
, :
LocalDate from = LocalDate.of(2020, 1, 1);
LocalDate to = LocalDate.of(2020, 1, 31);
from.datesUntil(to, Period.ofWeeks(1))
.forEach(System.out::println);
:
2020-01-01
2020-01-08
2020-01-15
2020-01-22
2020-01-29
:
3. Collection.toArray()
-
: Java 11
Java . Collection
Java 1.2 :
, ( String[]
), :
collection.toArray(new String[0])
. , , , .collection.toArray(new String[collection.size()])
. , , . .
, , IntelliJ IDEA , , .
2016 , , -: - ( JDK 6+). , IDEA , : (default), Java.
, «». Stream.toArray(IntFunction[])
collection.stream().toArray(String[]::new)
. ? , .
Oracle : , ? Java 11 Collection.toArray(IntFunction[])
, .
. , 4 , , :
List<Integer> list = ...;
Integer[] array = list.toArray(Integer[]::new);
4. InputStream
: readNBytes()
, readAllBytes()
, transferTo()
: Java 9 / Java 11
, Java – InputStream
. , Java 8 : , , , , , .. , .
Java 9 InputStream.readAllBytes()
, . , stdout
/stderr
:
Process proc = Runtime.getRuntime().exec("java -version");
try (InputStream inputStream = proc.getErrorStream()) {
byte[] bytes = inputStream.readAllBytes();
System.out.print(new String(bytes));
}
:
openjdk version "14-ea" 2020-03-17
OpenJDK Runtime Environment (build 14-ea+33-1439)
OpenJDK 64-Bit Server VM (build 14-ea+33-1439, mixed mode, sharing)
N
, Java 11 InputStream.readNBytes()
.
( ) InputStream
OutputStream
, InputStream.transferTo()
. , Java :
Process proc = Runtime.getRuntime().exec("java -version");
Path path = Path.of("out.txt");
try (InputStream inputStream = proc.getErrorStream();
OutputStream outputStream = Files.newOutputStream(path)) {
inputStream.transferTo(outputStream);
}
, Reader
Writer
: Reader.transferTo()
, Java 10.
5. Collectors.teeing()
: Java 12
Stream
. , Stream
Employee
, :
Java 8? , : Stream.count()
, Stream.filter()
Stream.count()
. , Stream
.
– Stream.forEach()
:
Stream<Employee> employees = ...
int[] countWithPhoneAndTotal = {0, 0};
employees
.forEach(emp -> {
if (emp.getPhoneNumber() != null) {
countWithPhoneAndTotal[0]++;
}
countWithPhoneAndTotal[1]++;
});
System.out.println("Employees with phone number: "
+ countWithPhoneAndTotal[0]);
System.out.println("Total employees: "
+ countWithPhoneAndTotal[1]);
, , , . Stream.peek()
.
Stream.reduce()
:
class CountWithPhoneAndTotal {
final int withPhone;
final int total;
CountWithPhoneAndTotal(int withPhone, int total) {
this.withPhone = withPhone;
this.total = total;
}
}
CountWithPhoneAndTotal countWithPhoneAndTotal = employees
.reduce(
new CountWithPhoneAndTotal(0, 0),
(count, employee) -> new CountWithPhoneAndTotal(
employee.getPhoneNumber() != null
? count.withPhone + 1
: count.withPhone,
count.total + 1),
(count1, count2) -> new CountWithPhoneAndTotal(
count1.withPhone + count2.withPhone,
count1.total + count2.total));
System.out.println("Employees with phone number: "
+ countWithPhoneAndTotal.withPhone);
System.out.println("Total employees: "
+ countWithPhoneAndTotal.total);
, , . -, , -, , CountWithPhoneAndTotal
. - , CountWithPhoneAndTotal
inline
, .
. - , Java 8 , . , Java 12 Collectors.teeing()
:
Entry<Long, Long> countWithPhoneAndTotal = employees
.collect(teeing(
filtering(employee -> employee.getPhoneNumber() != null, counting()),
counting(),
Map::entry
));
.
Collectors.teeing()
: , - . : toBoth
, collectingToBoth
, collectingToBothAndThen
, pairing
, bifurcate
, distributing
, unzipping
, forking
,… teeing
tee, T, . : .
6. Runtime.version()
: Java 9
Java . , ? , . , java.version
. java.specification.version
… , :
for (String key : Arrays.asList(
"java.version",
"java.runtime.version",
"java.specification.version",
"java.vm.version",
"java.vm.specification.version")) {
System.out.println(key + " = " + System.getProperty(key));
}
Java 8, :
java.version = 1.8.0_192
java.runtime.version = 1.8.0_192-b12
java.specification.version = 1.8
java.vm.version = 25.192-b12
java.vm.specification.version = 1.8
8? , java.specification.version
, 1.
, … , Java 9 :
java.version = 9.0.1
java.runtime.version = 9.0.1+11
java.specification.version = 9
java.vm.version = 9.0.1+11
java.vm.specification.version = 9
, Java 9 API Java 10. API «» , Runtime.version()
. Runtime.Version
, :
Runtime.Version version = Runtime.version();
System.out.println("Feature = " + version.feature());
System.out.println("Interim = " + version.interim());
System.out.println("Update = " + version.update());
System.out.println("Patch = " + version.patch());
, , JDK 11.0.5:
Feature = 11
Interim = 0
Update = 5
Patch = 0
7. Optional.isEmpty()
: Java 11
, , :
if (!stream.findAny().isPresent()) {
System.out.println("Stream is empty");
}
Optional.isEmpty()
, :
if (stream.findAny().isEmpty()) {
System.out.println("Stream is empty");
}
:
Stream<Optional<Integer>> stream = Stream.of(
Optional.of(1),
Optional.empty(),
Optional.of(2));
long emptyCount = stream
.filter(Optional::isEmpty)
.count();
8. HTTP-
: Java 11
API HTTP HttpURLConnection
, Java . , : , HTTP/2 -, , . HTTP Client, Java 9 , Java 11.
java.net.http
, HttpClient
. , HTTP- :
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest
.newBuilder(new URI("https://minijug.ru"))
.build();
HttpResponse<Stream<String>> response = client.send(request,
HttpResponse.BodyHandlers.ofLines());
System.out.println("Status code = " + response.statusCode());
System.out.println("Body = ");
response.body().limit(4).forEach(System.out::println);
:
Status code = 200
Body =
<!doctype html>
<html>
<head>
<title>miniJUG</title>
java.net.http
, , .
9. Lookup.defineClass()
: Java 9
? , , Java 8 . Unsafe.defineClass()
Unsafe.defineAnonymousClass()
, API, .
: , , MethodHandles.Lookup.defineClass()
, Java 9. :
import java.lang.invoke.MethodHandles;
import java.nio.file.Files;
import java.nio.file.Path;
public class Main {
public static void main(String[] args) throws Exception {
byte[] bytes = Files.readAllBytes(Path.of("Temp.class"));
Class<?> clazz = MethodHandles.lookup().defineClass(bytes);
Object obj = clazz.getDeclaredConstructor().newInstance();
System.out.println(obj);
}
}
class Temp {
@Override
public String toString() {
return "Hello from Temp!";
}
}
Temp
, Main
> javac Temp.java
> javac Main.java
> java Main
Hello from Temp!
, , Temp
Main
( , ). Temp
, - , Temp
, .
, , . defineClass()
, , . , . ToolProvider.getSystemJavaCompiler()
, java.compiler
( ).
10. ByteArrayOutputStream.writeBytes()
: Java 11
ByteArrayOutputStream.writeBytes()
– ByteArrayOutputStream.write()
: write()
throws IOException
, writeBytes()
– (IOException
write()
, OutputStream
). , Java 11, ByteArrayOutputStream
:
private static byte[] concat(Stream<byte[]> stream) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
stream.forEach(out::writeBytes);
return out.toByteArray();
}
: IndexOutOfBoundsException(int)
: Java 9
Java 9: IndexOutOfBoundsException
, , :
private static void doAtIndex(int index) {
if (index < 0) {
throw new IndexOutOfBoundsException(index);
}
}
public static void main(String[] args) {
doAtIndex(-1);
}
, 10 (+1) API, Java. ? , .