How can I avoid using an interface in java 8? - java

I just want to know if its possible to avoid the use of an interface in this code
public interface FunctionT<T,R> {
R apply(Integer...args);
}
public static FunctionT sum = (params) -> Arrays.asList(params)
.stream()
.reduce(Integer::sum).get();

The type of a lambda expression in Java is a functional interface. This means that the lambda must be provided with a target type that is a functional interface. This could be yours (FunctionT) or a standard one like java.util.function.Function.
Put another way, function types in Java are nominal, not structural.
(Also, you don't want to blindly call get() on an Optional, you want to use one of the safe methods like orElse() or ifPresent(). Otherwise you lose all the safety of using Optional in the first place.)

Related

How to use function interface, and use it as function argument?

I am not that good with function interface.
How to make Function<S, Set<S>> and how to send it as parameter?
public class Algorithms {
public static <S> Optional<Node<S>> search(S s0, Function<S, Set<S>> succ, Predicate<S> goal) {
.
.
.
return Optional.empty();
}
}
Any interface with exactly one non-default method is a functional interface, and Function meets that condition. That means you can implement it using a lambda expression. For example, let's say we're using this search function to search someone's family tree:
search(alice, (person) -> person.getChildren(), (person) -> person.getName().equals("Bob"));
The second argument, (person) -> person.getChildren(), creates a Function<Person, Set<Person>> that calls getChildren() on its argument. (We know it should accept a Person and return a Set<Person> from how we're passing it to search.) Likewise, the third argument creates a Predicate<Person> that checks if their name is "Bob".
Now, there are two "convenience" features I'm glossing over here. When the lambda only takes one argument (as is the case with both Function and Predicate), you can omit the parentheses around the name. Secondly, when a lambda only calls some method on its argument, you can use a method reference, which is just a more concise way of writing the lambda:
search(alice, Person::getChildren, person -> person.getName().equals("Bob"));
That's entirely equivalent, just more concise.
You can also implement functional interfaces the "old-school" way, i.e. by writing an (anonymous) class, but lambda syntax avoids a lot of boilerplate and is more readable. It's still fundamentally doing the same thing (and your IDE should be able to transform the one to the other, if that's helpful for you).

Why can't the var keyword in Java be assigned a lambda expression?

It is allowed to assign var in Java 10 with a string like:
var foo = "boo";
While it is not allowed to assign it with a lambda expression such as:
var predicateVar = apple -> apple.getColor().equals("red");
Why can't it infer a lambda or method reference type when it can infer the rest like String, ArrayList, user class, etc.?
This has nothing to do with var. It has to do with whether a lambda has a standalone type. The way var works is that it computes the standalone type of the initializer on the RHS, and infers that.
Since their introduction in Java 8, lambda expressions and method references have no standalone type -- they require a target type, which must be a functional interface.
If you try:
Object o = (String s) -> s.length();
you also get a type error, because the compiler has no idea what functional interface you intend to convert the lambda to.
Asking for inference with var just makes it harder, but since the easier question can't be answered, the harder one cannot either.
Note that you could provide a target type by other means (such as a cast) and then it would work:
var x = (Predicate<String>) s -> s.isEmpty();
because now the RHS has a standalone type. But you are better off providing the target type by giving x a manifest type.
From the Local-Variable Type Inference JEP:
The inference process, substantially, just gives the variable the type of its initializer expression. Some subtleties:
The initializer has no target type (because we haven't inferred it yet). Poly expressions that require such a type, like lambdas, method references, and array initializers, will trigger an error.
Because a lambda expression by itself does not have a type, it can not be inferred for var.
... Similarly, a default rule could be set.
Sure, you can come up with a way to work around this limitation. Why the developers made the decision not to do that is really up to speculation, unless someone who was part of the decision making can answer here. (Update: answered here.) If you're interested anyway, you could ask about it on one of the openjdk mailing lists: http://mail.openjdk.java.net/mailman/listinfo
If I were to guess, they probably didn't want to tie lambda inference in the context of var to a specific set of functional interface types, which would exclude any third party functional interface types. A better solution would be to infer a generic function type (i.e. (Apple) -> boolean) that can than be converted to a compatible functional interface type. But the JVM does not have such function types, and the decision to not implement them was already made during the project that created lambda expressions. Again if you're interested in concrete reasons, ask the devs.
To everyone who is saying this is impossible, undesired, or unwanted, I just want to point out that Scala can infer the lambda's type by specifying only the argument type:
val predicateVar = (apple: Apple) => apple.getColor().equals("red")
And in Haskell, because getColor would be a standalone function not attached to an object, and because it does full Hindley-Milner inference, you don't need to specify even the argument type:
predicateVar = \apple -> getColor apple == "red"
This is extraordinarily handy, because it's not the simple types that are annoying for programmers to explicitly specify, it's the more complex ones.
In other words, it's not a feature in Java 10. It's a limitation of their implementation and previous design choices.
As several people have already mentioned, what type should var infer and why should it?
The statement:
var predicateVar = apple -> apple.getColor().equals("red");
is ambiguous and there is no valid reason why the compiler should pick Function<Apple, Boolean> over Predicate<Apple> or vice versa assuming the apple identifier in the lambda represents an Apple isntance.
Another reason is that a lambda in its own doesn't have a speakable type hence there is no way for the compiler to infer it.
Also, "if this was possible" imagine the overhead as the compiler would have to go through all the functional interfaces and determine which functional interface is the most appropriate each time you assign a lambda to a var variable.
To answer this we have to go into details and understand what a lambda is and how it works.
First we should understand what a lambda is:
A lambda expression always implements a functional interface, so that when you have to supply a functional interface like Runnable, instead of having to create a whole new class that implements the interface, you can just use the lambda syntax to create a method that the functional interface requires. Keep in mind though that the lambda still has the type of the functional interface that it is implementing.
With that in mind, lets take this a step further:
This works great as in the case of Runnable, I can just create a new thread like this new Thread(()->{//put code to run here}); instead of creating a whole new object to implement the functional interface. This works since the compiler knows that Thread() takes an object of type Runnable, so it knows what type the lambda expression has to be.
However, in a case of assigning a lambda to a local variable, the compiler has no clue what functional interface this lambda is implementing so it can't infer what type var should be. Since maybe it's implementing a functional interface the user created or maybe it's the runnable interface, there is just no way to know.
This is why lambdas do not work with the var keyword.
Because that is a non-feature:
This treatment would be restricted to local variables with initializers, indexes in the enhanced for-loop, and locals declared in a traditional for-loop; it would not be available for method formals, constructor formals, method return types, fields, catch formals, or any other kind of variable declaration.
http://openjdk.java.net/jeps/286
In a nutshell, the types of a var and lambda expression both need inference, but in opposite way. The type of a var is inferred by the initializer:
var a = new Apple();
The type of a lambda expression is set by the context. The type expected by the context is called the target type, and is usually inferred by the declaration e.g.
// Variable assignment
Function<Integer, Integer> l = (n) -> 2 * n;
// Method argument
List<Integer> map(List<Integer> list, Function<Integer, Integer> fn){
//...
}
map(List.of(1, 2, 3), (n) -> 2 * n);
// Method return
Function<Integer, Integer> foo(boolean flag){
//...
return (n) -> 2 * n;
}
So when a var and lambda expression are used together, the type of the former needs to be inferred by the latter while the type of the latter needs to be inferred by the former.
var a = (n) -> 2 * n;
The root of this dilemma is Java cannot decide the type of a lambda expression uniquely, which is further caused by Java's nominal instead of structural type system. That is, two types with identical structures but different names are not deemed as the same, e.g.
class A{
public int count;
int value(){
return count;
}
}
class B{
public int count;
int value(){
return count;
}
}
Function<Integer, Boolean>
Predicate<Integer>

My confusion with Java Lambda expression

I know that Java's Lambda expression can replace a parameter whose type is an Interface (only contains one method), but why I can execute code like this:
String[] myArray = new String[3];
Arrays.sort(myArray, (a, b) -> {return b.compareTo(a);});
In this case, the lambda expression (a, b) -> {return b.compareTo(a);} replaces an object of Comparator interface, but Comparator interface has more than one method, why?
You can do this because Comparator only declares one method for which there is no default implementation. (You may notice that it redeclares equals without an implementation, but this is only to document the effect of overriding it in a Comparator. A default implementation is inherited from Object, as discussed here.)
From the JavaDocs for java.util.Comparator:
Functional Interface:
This is a functional interface and can therefore
be used as the assignment target for a lambda expression or method
reference.
java.util.Comparator is annotated with #FunctionalInterface which is:
used to indicate that an interface type declaration is intended to be a functional interface as defined by the Java Language Specification. Conceptually, a functional interface has exactly one abstract method.
The comparator interface contains only 1 method: compare(...)
Because of this it is a functional interface which can be used with lambdas.

Java 8 sort on Class member's property

Class declaration:
class Entity {
String name;
SubEntity subEntity; // subEntity has a method getAmount() which returns int
}
I understand with Java 8 we can sort like:
entities.sort(Comparator.comparing(Entity::name));
But is there a way I can sort it on sub-entities' properties, for eg:
entities.sort(Comparator.comparing(Entity::SubEntity::getAmount()));
P.S: All in for any one-liners.
Not by using a method reference, no - but it's easy to do with a lambda instead:
entities.sort(Comparator.comparing(entity -> entity.getSubEntity().getAmount()));
Fundamentally there's nothing magical about Comparator.comparing - it just accepts a Function<? super T,? extends U> keyExtractor parameter, so you need to work out some way of creating such a function. A method reference is one convenient way of creating a function, but a lambda expression is more flexible one.
Guys gave you good answers. It isn't supposed to be an improvement over their answers. I just want to provide an alternative idea.
entities.sort(Comparator.comparing(((Function<Entity, SubEntity>)Entity::getSubEntity).andThen(SubEntity::getAmount)));
I formed a key extractor by combining two functions Entity::getSubEntity and SubEntity::getAmount with Function#andThen. Both have been written as method references. The cast is required to determine the type of an instance and call andThen on that instance.
You can do that via a lambda as opposed to a method reference:
entities.sort(Comparator.comparing(x -> x.getSubEntity().getAmount())
If you you have indeed an int as you say in your comments, then use :
Comparator.comparingInt(...)

What are functional interfaces used for in Java 8?

I came across a new term in Java 8: "functional interface". I could only find one use of it while working with lambda expressions.
Java 8 provides some built-in functional interfaces and if we want to define any functional interface then we can make use of the #FunctionalInterface annotation. It will allow us to declare only a single method in the interface.
For example:
#FunctionalInterface
interface MathOperation {
int operation(int a, int b);
}
How useful it is in Java 8 other than just working with lambda expressions?
(The question here is different from the one I asked. It is asking why we need functional interfaces while working with lambda expressions. My question is: What are the other uses of functional interfaces besides use with lambda expressions?)
#FunctionalInterface annotation is useful for compilation time checking of your code. You cannot have more than one method besides static, default and abstract methods that override methods in Object in your #FunctionalInterface or any other interface used as a functional interface.
But you can use lambdas without this annotation as well as you can override methods without #Override annotation.
From docs
a functional interface has exactly one abstract method. Since default
methods have an implementation, they are not abstract. If an interface
declares an abstract method overriding one of the public methods of
java.lang.Object, that also does not count toward the interface's
abstract method count since any implementation of the interface will
have an implementation from java.lang.Object or elsewhere
This can be used in lambda expression:
public interface Foo {
public void doSomething();
}
This cannot be used in lambda expression:
public interface Foo {
public void doSomething();
public void doSomethingElse();
}
But this will give compilation error:
#FunctionalInterface
public interface Foo {
public void doSomething();
public void doSomethingElse();
}
Invalid '#FunctionalInterface' annotation; Foo is not a functional
interface
The documentation makes indeed a difference between the purpose
An informative annotation type used to indicate that an interface type declaration is intended to be a functional interface as defined by the Java Language Specification.
and the use case
Note that instances of functional interfaces can be created with lambda expressions, method references, or constructor references.
whose wording does not preclude other use cases in general. Since the primary purpose is to indicate a functional interface, your actual question boils down to “Are there other use cases for functional interfaces other than lambda expressions and method/constructor references?”
Since functional interface is a Java language construct defined by the Java Language Specification, only that specification can answer that question:
JLS §9.8. Functional Interfaces:
…
In addition to the usual process of creating an interface instance by declaring and instantiating a class (§15.9), instances of functional interfaces can be created with method reference expressions and lambda expressions (§15.13, §15.27).
So the Java Language Specification doesn’t say otherwise, the only use case mentioned in that section is that of creating interface instances with method reference expressions and lambda expressions. (This includes constructor references as they are noted as one form of method reference expression in the specification).
So in one sentence, no, there is no other use case for it in Java 8.
As others have said, a functional interface is an interface which exposes one method. It may have more than one method, but all of the others must have a default implementation. The reason it's called a "functional interface" is because it effectively acts as a function. Since you can pass interfaces as parameters, it means that functions are now "first-class citizens" like in functional programming languages. This has many benefits, and you'll see them quite a lot when using the Stream API. Of course, lambda expressions are the main obvious use for them.
Not at all. Lambda expressions are the one and only point of that annotation.
A lambda expression can be assigned to a functional interface type, but so can method references, and anonymous classes.
One nice thing about the specific functional interfaces in java.util.function is that they can be composed to create new functions (like Function.andThen and Function.compose, Predicate.and, etc.) due to the handy default methods they contain.
An interface with only one abstract method is called Functional Interface.
It is not mandatory to use #FunctionalInterface, but it’s best practice to use it with functional interfaces to avoid addition of extra methods accidentally. If the interface is annotated with #FunctionalInterface annotation and we try to have more than one abstract method, it throws compiler error.
package com.akhi;
#FunctionalInterface
public interface FucnctionalDemo {
void letsDoSomething();
//void letsGo(); //invalid because another abstract method does not allow
public String toString(); // valid because toString from Object
public boolean equals(Object o); //valid
public static int sum(int a,int b) // valid because method static
{
return a+b;
}
public default int sub(int a,int b) //valid because method default
{
return a-b;
}
}
Functional Interface:
Introduced in Java 8
Interface that contains a "single abstract" method.
Example 1:
interface CalcArea { // --functional interface
double calcArea(double rad);
}
Example 2:
interface CalcGeometry { // --functional interface
double calcArea(double rad);
default double calcPeri(double rad) {
return 0.0;
}
}
Example 3:
interface CalcGeometry { // -- not functional interface
double calcArea(double rad);
double calcPeri(double rad);
}
Java8 annotation -- #FunctionalInterface
Annotation check that interface contains only one abstract method. If not, raise error.
Even though #FunctionalInterface missing, it is still functional interface (if having single abstract method). The annotation helps avoid mistakes.
Functional interface may have additional static & default methods.
e.g. Iterable<>, Comparable<>, Comparator<>.
Applications of Functional Interface:
Method references
Lambda Expression
Constructor references
To learn functional interfaces, learn first default methods in interface, and after learning functional interface, it will be easy to you to understand method reference and lambda expression
You can use lambda in Java 8
public static void main(String[] args) {
tentimes(inputPrm - > System.out.println(inputPrm));
//tentimes(System.out::println); // You can also replace lambda with static method reference
}
public static void tentimes(Consumer myFunction) {
for (int i = 0; i < 10; i++)
myFunction.accept("hello");
}
For further info about Java Lambdas and FunctionalInterfaces
#FunctionalInterface is a new annotation are released with Java 8 and provide target types for lambda expressions and it used on compilation time checking of your code.
When you want to use it :
1- Your interface must not have more than one abstract methods, otherwise compilation error will be given.
1- Your interface Should be pure, which means functional interface is intended to be implemented by stateless classes, exmple of pure is Comparator interface because its not depend on the implementers state, in this case No compilation error will be given, but in many cases you will not be able to use lambda with this kind of interfaces
The java.util.function package contains various general purpose functional interfaces such as Predicate, Consumer, Function, and Supplier.
Also please note that you can use lambdas without this annotation.
Beside other answers, I think the main reason to "why using Functional Interface other than directly with lambda expressions" can be related to nature of Java language which is Object Oriented.
The main attributes of Lambda expressions are: 1. They can be passed around 2. and they can executed in future in specific time (several times). Now to support this feature in languages, some other languages deal simply with this matter.
For instance in Java Script, a function (Anonymous function, or Function literals) can be addressed as a object. So, you can create them simply and also they can be assigned to a variable and so forth. For example:
var myFunction = function (...) {
...;
}
alert(myFunction(...));
or via ES6, you can use an arrow function.
const myFunction = ... => ...
Up to now, Java language designers have not accepted to handle mentioned features via these manner (functional programming techniques). They believe that Java language is Object Oriented and therefore they should solve this problem via Object Oriented techniques. They don't want to miss simplicity and consistency of Java language.
Therefore, they use interfaces, as when an object of an interface with just one method (I mean functional interface) is need you can replace it with a lambda expression. Such as:
ActionListener listener = event -> ...;
Functional Interfaces: An interface is called a functional interface if it has a single abstract method irrespective of the number of default or static methods. Functional Interface are use for lamda expression. Runnable, Callable, Comparable, Comparator are few examples of Functional Interface.
KeyNotes:
Annotation #FunctionalInterface is used(Optional).
It should have only 1 abstract method(irrespective of number of default and static
methods).
Two abstract method gives compilation error(Provider #FunctionalInterface annotation is
used).
This thread talks more in detail about what benefit functional Interface gives over anonymous class and how to use them.

Categories

Resources