Java 12 - New Features

Java 12 - New Features

New String and Files methods

String.indent()

To indent a string, we used to write a small helper method that put the desired number of spaces in front of the String. If it should work over multiple lines, the method became correspondingly complex.

Java 12 has such a method built-in:?String.indent(). The following example shows how to indent a multiline string by four spaces:

String s = "I am\na multiline\nString.";
System.out.println(s);
System.out.println(s.indent(4));
        

The program prints the following:

I am
a multiline
String.
    I am
    a multiline
    String.
        

String.transform()

The new?String.transform()?method applies an arbitrary function to a String and returns the function's return value. Here are a few examples:

String uppercase = "abcde".transform(String::toUpperCase);
Integer i        = "12345".transform(Integer::valueOf);
BigDecimal big   = "1234567891011121314151617181920".transform(BigDecimal::new);
        

When you look at the source code of?String.transform(), you will notice that there is no rocket science at work. The method reference is interpreted as a function, and the String is passed to its?apply()?method:

public <R> R transform(Function<? super String, ? extends R> f) {
  return f.apply(this);
}
        

Then why use?transform()?instead of just writing the following?

String uppercase = "abcde".toUpperCase();
Integer i        = Integer.valueOf("12345");
BigDecimal big   = new BigDecimal("1234567891011121314151617181920");
        

The advantage of?String.transform()?is that the function to be applied can be determined dynamically at runtime, while in the latter notation, the conversion is fixed at compile time.

Files.mismatch()

You can use the?Files.mismatch()?method to compare the contents of two files.

The method returns -1 if both files are the same. Otherwise, it returns the position of the first byte at which both files differ. If one of the files ends before a difference is detected, the length of that file is returned.

The Teeing Collector

For some requirements, you may want to terminate a Stream with two collectors instead of one and combine the result of both collectors.

In the following example source code, we want to determine the difference from largest to smallest number from a stream of random numbers (we use?Optional.orElseThrow()?introduced in Java 10?to avoid a "code smell" blaming):

Stream<Integer> numbers = new Random().ints(100).boxed();

int min = numbers.collect(Collectors.minBy(Integer::compareTo)).orElseThrow();
int max = numbers.collect(Collectors.maxBy(Integer::compareTo)).orElseThrow();
long range = (long) max - min;
        

The program compiles but aborts at runtime with an exception:

Exception in thread "main" java.lang.IllegalStateException: 
        stream has already been operated upon or closed
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:229)
    at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
    at eu.happycoders.sandbox.TeeingCollectorTest.main(TeeingCollectorTest.java:12)        

The exception text lets us know that we may terminate a Stream only once.

How can we solve this task then?

One variant would be to write a custom collector that accumulates minimum and maximum in a 2-element int array:

Stream<Integer> numbers = new Random().ints(100).boxed();

int[] result =
    numbers.collect(
        () -> new int[] {Integer.MAX_VALUE, Integer.MIN_VALUE},
        (minMax, i) -> {
          if (i < minMax[0]) minMax[0] = i;
          if (i > minMax[1]) minMax[1] = i;
        },
        (minMax1, minMax2) -> {
          if (minMax2[0] < minMax1[0]) minMax1[0] = minMax2[0];
          if (minMax2[1] > minMax1[1]) minMax1[1] = minMax2[1];
        });

long range = (long) result[1] - result[0];
        

This approach is quite complex and not very legible.

We can do it easier using the "Teeing Collector" introduced in Java 12. We can specify two collectors (called downstream collectors) and a merger function that combines the results of the two collectors:

Stream<Integer> numbers = new Random().ints(100).boxed();

long range =
    numbers.collect(
        Collectors.teeing(
            Collectors.minBy(Integer::compareTo),
            Collectors.maxBy(Integer::compareTo),
            (min, max) -> (long) max.orElseThrow() - min.orElseThrow()));
        

Support for Compact Number Formatting

Using the static method?NumberFormat.getCompactNumberInstance(), we can create a formatter for the so-called "compact number formatting". This is a form that is easy for humans to read, such as "2M" or "3 billion".

The following example shows how some numbers are displayed – once in the short and once in the long compact form:

NumberFormat nfShort =
    NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
NumberFormat nfLong =
    NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.LONG);

System.out.println("        1,000 short -> " + nfShort.format(1_000));
System.out.println("      456,789 short -> " + nfShort.format(456_789));
System.out.println("    2,000,000 short -> " + nfShort.format(2_000_000));
System.out.println("3,456,789,000 short -> " + nfShort.format(3_456_789_000L));
System.out.println();
System.out.println("        1,000 long -> " + nfLong.format(1_000));
System.out.println("      456,789 long -> " + nfLong.format(456_789));
System.out.println("    2,000,000 long -> " + nfLong.format(2_000_000));
System.out.println("3,456,789,000 long -> " + nfLong.format(3_456_789_000L));
        

The program will print the following:

        1,000 short -> 1K
      456,789 short -> 457K
    2,000,000 short -> 2M
3,456,789,000 short -> 3B

        1,000 long -> 1 thousand
      456,789 long -> 457 thousand
    2,000,000 long -> 2 million
3,456,789,000 long -> 3 billion
        


要查看或添加评论,请登录

Ahmed El-Sayed的更多文章

  • Open System Architecture

    Open System Architecture

    "Open System Architecture" typically refers to the design and implementation of systems using open standards, open…

  • ChatGPT: Revolutionizing Conversational AI

    ChatGPT: Revolutionizing Conversational AI

    Artificial intelligence (AI) has come a long way in recent years, and one of the most exciting developments in this…

  • Togaf 9.2 Level 1 (Part 1)

    Togaf 9.2 Level 1 (Part 1)

    efore we go in details , we have to know how can we read the open group standards document, you should download the…

    1 条评论
  • Kafka vs RabbitMQ

    Kafka vs RabbitMQ

    What’s the Difference Between a Message Broker and a Publish/Subscribe (Pub/Sub) Messaging System? Message brokers are…

  • What is the strangler pattern and how does it work?

    What is the strangler pattern and how does it work?

    What is the strangler pattern? Picture a motorcycle that works, but could stand to undergo extensive overhauls that…

  • MIGRATING FROM MONOLITH TO MICROSERVICES: STRATEGY & STEP-BY-STEP GUIDE

    MIGRATING FROM MONOLITH TO MICROSERVICES: STRATEGY & STEP-BY-STEP GUIDE

    Migrating from monolith to microservices is less costly and risky than redeveloping an entire system from scratch. But…

    1 条评论
  • Migrate a monolith application to microservices using DDD

    Migrate a monolith application to microservices using DDD

    A monolithic application is typically an application system in which all of the relevant modules are packaged together…

    1 条评论
  • Migrate From Monolithic To Microservices Using DDD Pattern

    Migrate From Monolithic To Microservices Using DDD Pattern

    The general migration approach has three steps: Stop adding functionality to the monolithic application Split the…

  • Migrate From Monolithic To Microservices Using Strangler Pattern

    Migrate From Monolithic To Microservices Using Strangler Pattern

    There are three steps to transition from a monolithic application to microservices by implementing the Strangler…

  • GraalVM

    GraalVM

    GraalVM has caused a revolution in Java development since it launched three years ago. One of the most discussed…

社区洞察

其他会员也浏览了