What Is the Equivalent Lambda Expression for System.Out::Println

What is the equivalent lambda expression for System.out::println

The method reference System.out::println will evaluate System.out first, then create the equivalent of a lambda expression which captures the evaluated value. Usually, you would use
o -> System.out.println(o) to achieve the same as the method reference, but this lambda expression will evaluate System.out each time the method will be called.

So an exact equivalent would be:

PrintStream p = Objects.requireNonNull(System.out);
numbers.forEach(o -> p.println(o));

which will make a difference if someone invokes System.setOut(…); in-between.

Calling System.out.println() through a lambda expression

Your current attempt doesn't work because you're trying to declare a variable of type void - the equivalent would fail in C# too. You need to declare a variable of a suitable functional interface, just like you use a delegate type in C#.

You can do it with a lambda expression, but it would be cleaner (IMO) to use a method reference:

import java.util.function.Consumer;

public class Test {
public static void main(String[] args) {
Consumer<Object> c1 = x -> System.out.println(x);
Consumer<Object> c2 = System.out::println;

c1.accept("Print via lambda");
c2.accept("Print via method reference");
}
}

Here the Consumer<T> interface is broadly equivalent to the Action<T> delegate in .NET.

Similarly you can use a method group conversion in C# rather than a lambda expression:

public static Action<object> WL = Console.WriteLine;

What is the use of System.out::println in Java 8

It's called a "method reference" and it's a syntactic sugar for expressions like this:

numbers.forEach(x -> System.out.println(x));

Here, you don't actually need the name x in order to invoke println for each of the elements. That's where the method reference is helpful - the :: operator denotes you will be invoking the println method with a parameter, which name you don't specify explicitly:

numbers.forEach(System.out::println);

Equivalent lambda expression, to get a property of every object in a list

Assuming that your name attribute is a String, keep going with your Stream pipeline. Collect the names using the built-in Collector that joins the values with a separator in between each element: Collectors.joining:

Returns a Collector that concatenates the input elements, separated by the specified delimiter, in encounter order.

You can remove the unnecessary Arrays.asList, which is incorrect anyway; it takes an array, not a stream or a string, as an argument.

System.out.println(
dataSet.getAttributeList().stream()
.map(p -> p.getName())
.collect(Collectors.joining(" "))
);

You may also choose to use a method reference instead of a lambda expression:

.map(Attribute::getName)

is the type of System.out.println functional interface?

This part of code:

Consumer<Integer> consumer=System.out::println;

is equal to this lambda expression:

Consumer<Integer> consumer=i->System.out.println(i);

and above code block could be written in this way as an anonymous inner class using Consumer interface:

Consumer<Integer> consumer=new Consumer<Integer>(){
public void accept(Integer i){
System.out.println(i);
}
}

So "System.out.println" itself it is not a functional interface, but when you use :: you implicitly implement the Consumer interface.

Why my java lambda expression cannot work while its imperative style works properly?

As explained in What is the equivalent lambda expression for System.out::println, the method reference System.out::println is not identical to the lambda expression x -> System.out.println(x).

The method reference captures the current value of System.out, to invoke println on it each time the function is invoked, rather than evaluating System.out again each time as the lambda expression’s body does.

As also said, this rarely makes a difference, but here, it does. When you try to serialize the function, it will try to serialize all captured values, including the PrintStream instance read from System.out during the instantiation. The PrintStream is not serializable and it would be quite challenging to implement a serializable PrintStream fulfilling the expectations.

But it’s important to keep in mind that when you serialize the lambda expression x -> System.out.println(x) or an equivalent class object and deserialize it in a different environment, the System.out it will read there will evaluate to a different PrintStream than in your original environment. This doesn’t matter when the distributed computing framework takes care to pipe everything printed to the standard output back to the originator.

But it’s important to keep in mind that static fields which are not part of the serialized data may have different contents in different environments in general.



Related Topics



Leave a reply



Submit