APIs, für die es sich endlich lohnt, ein Upgrade von Java 8 durchzuführen. Teil 2

Wir setzen die Geschichte über die APIs fort, die in neuen Versionen von Java erschienen sind.



1. Files.mismatch()


Erschienen in: Java 12


In der Praxis muss häufig überprüft werden, ob zwei Dateien genau gleich sind oder nicht. Mit der Files.mismatch()in Java 12 eingeführten Methode kann dies endlich geschehen. Diese Methode gibt die Position des ersten Nichtübereinstimmungsbytes in zwei Dateien zurück oder -1wenn die Dateien identisch sind.


Dies kann beispielsweise nützlich sein, wenn Sie den Inhalt zweier Verzeichnisse synchronisieren. Um die Datei beim Kopieren mit demselben Inhalt nicht zu überschreiben und die Festplatte nicht erneut zu laden, können Sie zunächst überprüfen, ob die Dateien identisch sind oder nicht:


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);
            }
        }
    }
}

(Übrigens, wann werden sie endlich Streamerben Iterable? Ich möchte nur schreiben for (Path file : stream)und nicht mit den Zwischenlisten herumspielen.)


2. Neue Methoden in java.time


Eingeführt in: Java 9


Java hat seit fast 20 Jahren keine normale API für die Arbeit mit Datum und Uhrzeit. Dieses Problem wurde erst in Java 8 gelöst, als java.timeunter Anleitung des berüchtigten Stephen Colborn , dem Schöpfer der Joda Time- Bibliothek, ein neues Paket eingeführt wurde . Und in der neunten Version java.timewurden viele interessante Methoden hinzugefügt.


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