3

I am working with anonymous functions and functional interfaces, I have one functional interface that takes two objects of same type and returns true or false.

package elementutils;
@FunctionalInterface
public interface TwoElementPredicate <T> {
    public boolean compare(T a, T b);
    }

I use the functional interface in another class to get the "better element" using anonymous functions, the method betterElement takes two objects and the instance of the functional interface. Then i should be able to create lambdas to compare two objects of the same type in the main.

package elementutils;

public class ElementUtils <T> {
    public  T  betterElement(T a, T b, TwoElementPredicate elements){
    if (elements.compare(a, b) == true) {
        return a;
    }else {
        return b;
    }
    }
    public static void main(String[] args) {
        //String x= ElementUtils.betterElement("java", "python", (a, b) -> a.length() < b.length());
        //int y= ElementUtils.betterElement(2, 3, (a, b) -> a > b);
        //double z= ElementUtils.betterElement(2.5, 3.7, (a, b) -> a > b);
        // all this give errors

    }

}

The functions should take any object as long as they are from the same type. I thought I could achieve that using generic classes but when I instantiate the lambdas it seems that the elements are always of type object so I cannot use length() and cannot assigne them to a String for example.

I hope I explained myself correctly, any help will be highly appreciated.

Mureinik
  • 297,002
  • 52
  • 306
  • 350
  • *I hope i explained myself correctly*: no. What code did you try to compile/execute? What did you expect to happen? What happened instead? Precisely? – JB Nizet Jul 11 '18 at 17:29
  • I tried to excute the code in main, the one that's commented. I get only objects when i want different types: string, int, doubles. – Nadia Rodriguez Jul 11 '18 at 17:33
  • 1
    Don't paraphrase errors you get. Post them. *I expect this code to compile, but instead, I get the following error: * – JB Nizet Jul 11 '18 at 17:34
  • See also [*What is a raw type and why shouldn't we use it?*](https://stackoverflow.com/q/2770321/2891664) – Radiodef Jul 11 '18 at 17:38
  • 1
    Also, don't ignore compiler warnings. – chrylis -cautiouslyoptimistic- Jul 11 '18 at 17:41
  • 1
    As a side note, with the way you're calling the `betterElement` method, it looks like you meant to declare it as `public static T betterElement(...)` instead of putting the type parameter on the class. – Radiodef Jul 11 '18 at 17:41
  • 1) `betterElement()` is an instance method. You can't call it statically. 2) Java already has a `BiPredicate` interface. 3) If the point is to select one of the inputs, why don't you actually return it? – shmosel Jul 11 '18 at 17:44
  • It is homework, I am supposed to do it that way. – Nadia Rodriguez Jul 11 '18 at 18:20
  • Never use a construct like `if (elements.compare(a, b) == true)` in Java. The left side of the comparison is already a boolean expression, hence you should only write `if(elements.compare(a, b))`. If you understand the ternary operator, you can replace the entire `if` statement with a simple `return elements.compare(a, b)? a: b;`. – Holger Aug 22 '18 at 13:33

2 Answers2

4

You are missing the type parameter T on TwoElementPredicate and hence you are using a raw type

You need to declare the parameter elements as of type TwoElementPredicate<T>

Thiyagu
  • 17,362
  • 5
  • 42
  • 79
2

Your definition of betterElement uses a raw TwoElementPredicate, so its arguments will always be Objects. Instead, you should use a generic parameter, with the same T as the elements:

public T betterElement(T a, T b, TwoElementPredicate<T> elements) {
    // Here ----------------------------------------^
Mureinik
  • 297,002
  • 52
  • 306
  • 350