Two bellow snippets with the same output, one with using Functional interface and lambda expression, while the other snippet uses two simple method and easy to understand. What are the benefits first snippet code while it increases complexity.
First:
interface StringFunction {
String run(String str);
}
public class Main {
public static void main(String[] args) {
StringFunction exclaim = (s) -> s + "!";
StringFunction ask = (s) -> s + "?";
printFormatted("Hello", exclaim);
printFormatted("Hello", ask);
}
public static void printFormatted(String str, StringFunction format) {
String result = format.run(str);
System.out.println(result);
}
}
Second:
public class Main {
public static void main(String[] args) {
System.out.println(exclaim("Hello"));
System.out.println(ask("Hello"));
}
static String exclaim(String s) {
return s + "!";
}
static String ask(String s) {
return s + "?";
}
}
In the first example, you are passing a behaviour which you can change for every call in a much cleaner and succinct way than your second way e.g.
StringFunction exclaim = s -> s + "!";
printFormatted("Hello", exclaim);
exclaim = s -> s + "!!!";
printFormatted("Hello", exclaim);
If you have to do it in your second way, you will have to write another method for it.
On a side note, in your lambda expression, you do not need the parenthesis in case of a single parameter i.e. you can write it simply as (I've already done this way in the code above):
StringFunction exclaim = s -> s + "!";
StringFunction ask = s -> s + "?";
Biggest advantage of lambda expressions is they are focused on expression instead of object's state.
That means you specify exactly what you wants without dealing with object you pass
there. This allows you to use any object and get result you are expecting.
After all lambdas are still interfaces defining behavior as any other interfaces and depends on their implementation in concrete class.
Your provided code snippet is missing bigger complexity so lambda seems to be overkill there. But in complex systems it supports better maintainability and get rid of tight coupling
Related
This the following a good design if I wanted to call a method to a method?
The code below is this just an example.
public Enigma(){
String sentences = "This ";
method1(sentences);
}
public void method1(String x){
x = x + "a ";
method2(x);
}
public void method2(String x){
x = x + "test ";
method3(x);
}
public String method3(String x){
x = x + "!";
return x;
}
If those methods are only called from the constructor, then there's no point in making them public.
Also, usually you'd call method1 from the outside after creating the Enigma object.
Finally, as you may know chaining calls like that may lead to code that is difficult to understand and follow.
But if your question is related to "does this work", the answer is simply yes :)
I believe you are on the right track. Even if your example doesn't do anything concrete, I believe it is a good idea to point out possible flaws.
The class name has to be the same name of its Java file. For example, your class "Enigma" has to be written in the "Enigma.java" file. Otherwise, problems can appear. Often it is a good thing to remember.
Note that you can call method3 from method2 in a way that uses the output of this function.
public method2(String x) {
x = x + "a ";
x = x + method3(x)
}
Note that this example is only to show you how you can retrieve the value of the method you just called. You can always simply call this method the same way you call a void even if the method returns something. Both options work, it is for you to decide what your program has to do and how, depending on the context.
Overall, the correct Java syntax for your class is this one:
public class Enigma {
//put your class properties here
public Enigma(){
String sentences = "This ";
method1(sentences);
}
public void method1(String x) {
x = x + "a "; method2(x);
}
public void method2(String x) {
x = x + "test "; method3(x);
}
public String method3(String x) {
x = x + "!";
return x;
}
}
After this, if you are using Enigmaa as an object, you might want to add a constructor. If Enigma is not an object, use static methods by writing static just before your method return type in the declaration. For example: public void method1(String x) { would become public static void method1(String x) {. Doing so when possible is a good way to keep simple a program that acts like a script.
I wrote a sort function and class in Java:
public class MiscellaneousUtilities {
/**
* Changes a list of "First Last" to "Last, First" and "First Middle Last" to "Last, First Middle", etc.
*/
public static Function<String, String> ToLastFirstFunction = new Function<String, String>() {
#Override
public String apply(String nm) {
String[] nmarr = nm.split(" ");
int last = nmarr.length - 1;
String res = nmarr[last];
if (last > 0) {
res += ",";
}
for (int i = 0; i < last; i++) {
res += " " + nmarr[i];
}
return res;
};
};
}
When I want to use it I can't just say MiscellaneousFunctions.ToFirstLastFunction()
I have to do a new MiscellaneousFunctions().ToFirstLastFunction;
I tried putting static in front of the class declaration but it allows only public, final and abstract. Looking at the Math class if I want to use Math.min() I don't have to do a new Math().min(). Math is also defined as a class that does not have static in front of it, and min() does as does ToFirstLastFunction, so I don't understand the difference.
That's because you have to call that function with an apply like this:
MiscellaneousFunctions.ToFirstLastFunction.apply("yourstring");
You can add an other static function as a shorthand though:
public static String toFirstLast(String str) {
return ToLastFirstFunction.apply(str);
}
The main difference between Math.min and your solution that Math.min is a regular static method while you have a Function object and those can be called with apply.
Math.min() is a a method not a function, declared like this in Math.class:
public int min(int a, int b) {
...
}
... and it is methods like this that you can invoke directly as in int x = Math.min(3,2).
You have created a public static class variable called ToLastFirstFunction -- that's not something you can call like a method. But you can do things with it using the methods in the java.util.function.Function interface -- the simplest being apply():
String out = MiscellaneousFunctions.toFirstLastFunction.apply("John Doe");
(I changed the capitalisation of your identifier -- find out about Java capitalisation conventions)
It is not the case that you can call your public static Function<...> using new MiscellaneousFunctions().toFirstLastFunction("John Doe") -- I'm not sure why you thought it was so.
You can do new MiscellanousFunctions().toFirstLastFunction.apply("John Doe") -- but your compiler should warn you about accessing a static variable via an instance. MiscellanousFunctions.toFirstLastFunction.apply() is the right way.
So the short answer to your question is: if you want to invoke it that way, write it as a method.
But if that's the case, why would you define an operation as a function, rather than a method?
Well, functions have the benefit that, unlike methods(*), they are objects -- so you can pass them around, put them in collections, assign them to variables. And they have methods like compose() and andThen() which return a new function that combines this function with another.
So you can do things like:
Map<String,Function<String,String> nameTranslationStrategies = new HashMap<>();
nameTranslationStrategies.put(
"no change", x -> x);
nameTranslationStrategies.put(
"to first-last",
MiscellaneousFunctions.toFirstLastFunction);
nameTranslationStrategies.put(
"capitalised first-last",
MiscellaneousFunctions.toFirstLastFunction
.andThen( s -> s.toUpperCase());
...
String nameTranslationOption = config.getProperty("nameTranslationOption");
String name = nameTranslationStrategies
.get(nameTranslationOption)
.apply(inputString);
Java programmers managed for decades without this feature -- functions didn't exist until Java 8. But you can do lots of neat things with them.
Even so, this isn't a reason to write your code as a Function bound to a static variable, since you can access ordinary methods as functions using the :: syntax:
Function<Double,Double> logarithm = Math::log;
double x = logarithm.apply(2.0);
Note also, that you've used a long-winded syntax to define your function:
public static Function<String, String> slimify = new Function<String, String>() {
#Override
public String apply(String s) {
return "slim says " + s;
}
}
... can be written as:
public static Function<String,String> slimify = s -> {
return "slim says " + s;
}
... or even (since this one's a one-liner)
public static Function<String,String> slimify = s -> "slim says " + s;
It's good to know the long-winded way, because it shows how functions work behind the scenes. But in real world code, the shorter form is the way to go, as it is more expressive: the intent of the code isn't hidden by clutter. This is such a quick and easy way of expressing a function, that people often use them in-line rather than assign them to a variable -- as I have done in the map example above.
(*) I said that methods are not objects. This isn't strictly true -- partly because you can get one as an object using ::, but also because you can use Java's Reflection API to access classes and methods as objects. But you don't want to use Reflection, unless you really know you need to.
Math.min() is a public static method called min, your Function is a Function object, it's not a method. Your object has a method apply and you have to use that method for what you want to achieve, like this:
MiscellaneousFunctions.ToFirstLastFunction.apply(something)
This is based on this question. Consider this example where a method returns a Consumer based on a lambda expression:
public class TestClass {
public static void main(String[] args) {
MyClass m = new MyClass();
Consumer<String> fn = m.getConsumer();
System.out.println("Just to put a breakpoint");
}
}
class MyClass {
final String foo = "foo";
public Consumer<String> getConsumer() {
return bar -> System.out.println(bar + foo);
}
}
As we know, it's not a good practice to reference a current state inside a lambda when doing functional programming, one reason is that the lambda would capture the enclosing instance, which will not be garbage collected until the lambda itself is out of scope.
However, in this specific scenario related to final strings, it seems the compiler could have just enclosed the constant (final) string foo (from the constant pool) in the returned lambda, instead of enclosing the whole MyClass instance as shown below while debugging (placing the breaking at the System.out.println). Does it have to do with the way lambdas are compiled to a special invokedynamic bytecode?
In your code, bar + foo is really shorthand for bar + this.foo; we're just so used to the shorthand that we forget we are implicitly fetching an instance member. So your lambda is capturing this, not this.foo.
If your question is "could this feature have been implemented differently", the answer is "probably yes"; we could have made the specification/implementation of lambda capture arbitrarily more complicated in the aim of providing incrementally better performance for a variety of special cases, including this one.
Changing the specification so that we captured this.foo instead of this wouldn't change much in the way of performance; it would still be a capturing lambda, which is a much bigger cost consideration than the extra field dereference. So I don't see this as providing a real performance boost.
If the lambda was capturing foo instead of this, you could in some cases get a different result. Consider the following example:
public class TestClass {
public static void main(String[] args) {
MyClass m = new MyClass();
m.consumer.accept("bar2");
}
}
class MyClass {
final String foo;
final Consumer<String> consumer;
public MyClass() {
consumer = getConsumer();
// first call to illustrate the value that would have been captured
consumer.accept("bar1");
foo = "foo";
}
public Consumer<String> getConsumer() {
return bar -> System.out.println(bar + foo);
}
}
Output:
bar1null
bar2foo
If foo was captured by the lambda, it would be captured as null and the second call would print bar2null. However since the MyClass instance is captured, it prints the correct value.
Of course this is ugly code and a bit contrived, but in more complex, real-life code, such an issue could somewhat easily occur.
Note that the only true ugly thing, is that we are forcing a read of the to-be-assigned foo in the constructor, through the consumer. Building the consumer itself is not expected to read foo at that time, so it is still legit to build it before assigning foo – as long as you don't use it immediately.
However the compiler will not let you initialize the same consumer in the constructor before assigning foo – probably for the best :-)
You are right, it technically could do so, because the field in question is final, but it doesn't.
However, if it is a problem that the returned lambda retains the reference to the MyClass instance, then you can easily fix it yourself:
public Consumer<String> getConsumer() {
String f = this.foo;
return bar -> System.out.println(bar + f);
}
Note, that if the field hadn't been final, then your original code would use the actual value at the time the lambda is executed, while the code listed here would use the value as of the time the getConsumer() method is executed.
Note that for any ordinary Java access to a variable being a compile-time constant, the constant value takes place, so, unlike some people claimed, it is immune to initialization order issues.
We can demonstrate this by the following example:
abstract class Base {
Base() {
// bad coding style don't do this in real code
printValues();
}
void printValues() {
System.out.println("var1 read: "+getVar1());
System.out.println("var2 read: "+getVar2());
System.out.println("var1 via lambda: "+supplier1().get());
System.out.println("var2 via lambda: "+supplier2().get());
}
abstract String getVar1();
abstract String getVar2();
abstract Supplier<String> supplier1();
abstract Supplier<String> supplier2();
}
public class ConstantInitialization extends Base {
final String realConstant = "a constant";
final String justFinalVar; { justFinalVar = "a final value"; }
ConstantInitialization() {
System.out.println("after initialization:");
printValues();
}
#Override String getVar1() {
return realConstant;
}
#Override String getVar2() {
return justFinalVar;
}
#Override Supplier<String> supplier1() {
return () -> realConstant;
}
#Override Supplier<String> supplier2() {
return () -> justFinalVar;
}
public static void main(String[] args) {
new ConstantInitialization();
}
}
It prints:
var1 read: a constant
var2 read: null
var1 via lambda: a constant
var2 via lambda: null
after initialization:
var1 read: a constant
var2 read: a final value
var1 via lambda: a constant
var2 via lambda: a final value
So, as you can see, the fact that the write to the realConstant field did not happen yet when the super constructor is executed, no uninitialized value is seen for the true compile-time constant, even when accessing it via lambda expression. Technically, because the field isn’t actually read.
Also, nasty Reflection hacks have no effect on ordinary Java access to compile-time constants, for the same reason. The only way to read such a modified value back, is via Reflection:
public class TestCapture {
static class MyClass {
final String foo = "foo";
private Consumer<String> getFn() {
//final String localFoo = foo;
return bar -> System.out.println("lambda: " + bar + foo);
}
}
public static void main(String[] args) throws ReflectiveOperationException {
final MyClass obj = new MyClass();
Consumer<String> fn = obj.getFn();
// change the final field obj.foo
Field foo=obj.getClass().getDeclaredFields()[0];
foo.setAccessible(true);
foo.set(obj, "bar");
// prove that our lambda expression doesn't read the modified foo
fn.accept("");
// show that it captured obj
Field capturedThis=fn.getClass().getDeclaredFields()[0];
capturedThis.setAccessible(true);
System.out.println("captured obj: "+(obj==capturedThis.get(fn)));
// and obj.foo contains "bar" when actually read
System.out.println("via Reflection: "+foo.get(capturedThis.get(fn)));
// but no ordinary Java access will actually read it
System.out.println("ordinary field access: "+obj.foo);
}
}
It prints:
lambda: foo
captured obj: true
via Reflection: bar
ordinary field access: foo
which shows us two things,
Reflection also has no effect on compile-time constants
The surrounding object has been captured, despite it won’t be used
I’d be happy to find an explanation like, “any access to an instance field requires the lambda expression to capture the instance of that field (even if the field is not actually read)”, but unfortunately I couldn’t find any statement regarding capturing of values or this in the current Java Language Specification, which is a bit frightening:
We got used to the fact that not accessing instance fields in a lambda expression will create an instance which doesn’t have a reference to this, but even that isn’t actually guaranteed by the current specification. It’s important that this omission gets fixed soon…
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?
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".
#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.
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"));
System.getProperties().list(System.out);
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));
});
}
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()));
I have done some searching on the difference in implementing a closure using an anonymous class and a local class. I am trying to figure out all the differences between the two so I know which method is better in which situations.
Correct me if I am wrong:
The anonymous class has a class instance and object instance created each time a new instance is created.
The local class has only an object instance create each time a new instance is created.
Therefore, is there ever a time or place where I should use an anonymous class over a local class?
EDIT: It appears there is no real difference between the two, just depends on style and if you want to reuse the class.
To clarify what I mean here is an example of what I am talking about:
public class ClosureExample {
interface Function {
void func(int value);
}
public static void main(final String[] args) {
final Function local1 = localClassClosure("Local1");
final Function local2 = localClassClosure("Local2");
final Function anonymous1 = anonymousClassClosure("Annonymous1");
final Function anonymous2 = anonymousClassClosure("Annonymous2");
for (int i = 0; i < 3; i++) {
local1.func(i);
local2.func(i);
anonymous1.func(i);
anonymous2.func(i);
}
}
private static Function localClassClosure(final String text) {
// Local class name is irrelevant in this example
class _ implements Function {
#Override public void func(final int value) {
System.out.println(text + ":" + value);
}
}
return new _();
}
private static Function anonymousClassClosure(final String text) {
return new Function() {
#Override public void func(final int value) {
System.out.println(text + ":" + value);
}
};
}
}
Hopefully, someone can explain in detail this subtle difference and which method should be used in which situations.
This piqued my interest, and I broke out JD-GUI to look at the decompiled classes. There is actually no difference at all between the two anonymous inner classes after compilation:
localClass:
class ClosureExample$1t implements ClosureExample.Function{
ClosureExample$1t(String paramString){
}
public void func(int value){
System.out.println(this.val$text + ":" + value);
}
}
anonymousClass:
class ClosureExample$1 implements ClosureExample.Function{
ClosureExample$1(String paramString){
}
public void func(int value){
System.out.println(this.val$text + ":" + value);
}
}
Both methods are valid ways of implementing an anonymous inner class, and they seem to do the exact same thing.
EDIT: I renamed the _ class to t
I am pretty sure there is nothing like object instance, just class instance .
So yes an object is created for both local and anonymous types..
The difference however is you can't reuse the anonymous class (except through the way you used it in your method - which works but not really maintainable), so you use it when whatever you are doing is a one off thing. For example with event listeners.
I would prefer named types to anonymous types though.
You might find this useful
EDIT:
You will find my question here useful.
Just a note about this:
Therefore, is there ever a time or place where I should use an anonymous class over a local class?
If you need to quickly setup an event listener [e.g. a KeyListener] inside a component, you can do like this:
addKeyListener(new KeyListener(){
public void keyPressed(KeyEvent ke){ ... }
// further implementation here
});
Though it won't be reusable at all.
The local class object is faster at initialization (because the class is already in memory at startup)
The anonymous class object less memory consuming (because of the lazy evaluation)
Notice : Because java is not a real functional language. Anonymous classes will be pre-evaluated and even stored in class files. So really there wont be much difference.
In a functional language, like scheme :
(define inc (lambda (a) (lambda () (+ 1 a))))
(display ((inc 5)))
The function (lambda () (+ 1 a)) will be actually recreated at each anonymous call like ((inc 5)). This is the concept behind anonymous classes.
As opposed to:
(define inc (lambda (a) (+ 1 a)))
(display (inc 5))
Where (lambda (a) (+ 1 a)) will be stored in memory at compile time, and the call to (inc 5) will only reference it. This is the concept behind local classes.