API yang akhirnya layak ditingkatkan dari Java 8. Bagian 2

Kami melanjutkan kisah tentang API yang muncul di versi baru Java.



1. Files.mismatch()


Muncul di: Java 12


Dalam praktiknya, seringkali perlu untuk memeriksa apakah dua file persis sama atau tidak. Menggunakan metode yang Files.mismatch()diperkenalkan di Java 12, ini akhirnya bisa dilakukan. Metode ini mengembalikan posisi byte ketidakcocokan pertama dalam dua file, atau -1jika file tersebut identik.


Ini dapat bermanfaat, misalnya, ketika Anda menyinkronkan konten dari dua direktori. Agar tidak menimpa file saat menyalin dengan konten yang sama dan tidak memuat disk sekali lagi, Anda dapat terlebih dahulu memeriksa apakah file tersebut identik atau tidak:


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

(Ngomong-ngomong, kapan mereka akhirnya akan Streammewarisi Iterable? Aku hanya ingin menulis for (Path file : stream), dan tidak main-main dengan daftar perantara.)


2. Metode baru dalam java.time


Diperkenalkan di: Jawa 9


Selama hampir 20 tahun, Java belum memiliki API normal untuk bekerja dengan tanggal dan waktu. Masalah ini hanya terpecahkan di Jawa 8 ketika mereka memperkenalkan paket baru di java.timebawah bimbingan Stephen Colborn yang terkenal , pencipta perpustakaan Joda Time . Dan dalam versi kesembilan java.time, banyak metode menarik ditambahkan.


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