'How would I print the JVM's system properties using Java 8 and lambdas?

You can obtain a Properties instance of the JVM properties using System.getProperties(); how would you go about using Java 8 code to print all properties to the console?



Solution 1:[1]

One solution:

public final class Foo
{
    private static void printProperty(final Object key, final Object value)
    {
        System.out.println(key + ": " + value);
    }

    public static void main(final String... args)
    {
        System.getProperties().forEach(Foo::printProperty);
    }
}

Rundown:

  • Properties extends Hashtable<Object, Object> which itself implements Map<Object, Object>;
  • Map has a .forEach() method whose argument is a BiConsumer;
  • BiConsumer is a functional interface;
  • static method printProperty() of class Foo happens to have the same signature as a BiConsumer<Object, Object>: its "return value" is void, its first argument is Object, its second argument is Object;
  • we can therefore use Foo::printProperty as a method reference.

A shorter version would be:

public final class ShorterFoo
{
    public static void main(final String... args)
    {
        System.getProperties()
            .forEach((key, value) -> System.out.println(key + ": " + value));
    }
}

At runtime, this would not make a difference. Note the type inference in the second example: the compiler can infer that key and value are of type Object. Another way to write this "anonymous lambda" would have been:

(Object key, Object value) -> System.out.println(key + ": " + value)

(not so) Side note: even though it is a little outdated, you really want to watch this video (yes, it's one hour long; yes, it is worth watching it all).


(not so) Side note 2: you may have noticed that Map's .forEach() mentions a default implementation; this means that your custom Map implementations, or other implementations from external libraries, will be able to use .forEach() (for instance, Guava's ImmutableMaps). Many such methods on Java collections exist; do not hesitate to use these "new methods" on "old dogs".

Solution 2:[2]

@fge has missed one very short version that admittedly depends on the toString implementation of Map.Entry.

public class VeryShortFoo {
    public static void main(String... args) {
        System.getProperties().entrySet().forEach(System.out::println);
    }
}
  • Here, the entrySet is streamed and each Map.Entry is printed with a reference to out.println.
  • Map.Entry implementations of toString generally return getKey() + "=" + getValue().

Here's another one I quite like.

public class ElegantFoo {
    public static void main(String... args) {
        System.getProperties().entrySet().stream()
            .map(e -> e.getKey() + ": " + e.getValue())
            .forEach(System.out::println);
    }
}
  • The entrySet is streamed again (this time explicitly with a call to stream).
  • Stream#map performs a 1:1 conversion from elements of one type to elements of another. Here, it turns a Stream<Map.Entry> in to a Stream<String>.
  • The Stream<String> is printed.

Solution 3:[3]

In Java 8, the Properties class inherits a new method from HashTable called forEach. This new method accepts functions (functional interfaces) to be passed to it as arguments. To be more specific, it accepts the functional interface BiConsumer<T,U>. This functional interface's functional method is accept(T t, U u). In Java 8, all functional interfaces can be written as Lambda expressions. Therefore, here is how we would display all properties in a Property instance:

Properties vmProps = System.getProperties();
vmProps.forEach((t,u) -> System.out.println("Property: " + t + "\nValue: " + u + "\n"));

Solution 4:[4]

System.getProperties().list(System.out);

Solution 5:[5]

Sorted by key. This makes the output easier to read.

printProperties(System.getProperties());

public static void printProperties(Properties properties) {
    new TreeSet<>(properties.keySet()).forEach((k) -> {
        System.out.println(k + " : " + properties.get(k));
    });
}

Solution 6:[6]

public static void main(String[] args) {

        System.getProperties().keySet().forEach((k)-> System.out.println(k + "   ::::   "+ System.getProperty(k.toString())) );

    }

Shortest Version for me :D The following for System Variables

System.getenv().forEach((String env, String val) -> System.out.println(new StringBuilder(env).append("  =>>  ").append(val).toString()));

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 programmar
Solution 4 mlapeyre
Solution 5
Solution 6 Leonard Schiller