API pour lesquelles il vaut enfin la peine de passer de Java 8. Partie 2

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 -1si 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 Streamhé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.timesous 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, :


  • Stream.
  • , .

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) //  opt -> !opt.isPresent()
    .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 = ");
//  4 
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. :


// Main.java
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);
    }
}

// Temp.java
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::write); ( )
    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) {
    // java.lang.IndexOutOfBoundsException: Index out of range: -1
    doAtIndex(-1);
}


, 10 (+1) API, Java. ? , .

Source: https://habr.com/ru/post/undefined/


All Articles