'java.util.ArrayList' cannot be applied to '(<lambda parameter>)' - java

How can I fix this problem?
rv_groupAddMember.setAdapter(new GroupAdapter(groupModelList, position -> {
selectedGroup = groupModelList.get(position);
addMember_groupName.setText("Seçili Grup :"+selectedGroup.getGroupName());
}));
public class GroupAdapter extends RecyclerView.Adapter<GroupAdapter.GroupViewHolder>{
List<GroupModel> groupModelList;
OnClickItem onClickItem;
public GroupAdapter(List<GroupModel> groupModelList, OnClickItem onClickItem) {
this.groupModelList = groupModelList;
this.onClickItem = onClickItem;
}
I added my GroupAdapter class and constructor
error
I'm watching tutorial everything is the same and there shouldn't be an error.

The problem is, java needs to figure out what the lambda is actually trying to be, and only then can it know what the type of position is. For example, given:
void foo(Consumer<String> x) { ... }
If you then write: foo(s -> System.out.println(s)); - java knows that the type of s is String only because of this sequence of events:
There is only one foo method.
That method takes a param of type Consumer<String>.
That type is a functional interface (an interface with a single method), and that method's signature is void accept(String t).
The lambda is an implementation of that method, therefore, s must be String.
And only then can java continue to actually understand what the lambda contains.
Your error is telling you in a somewhat odd way that the compiler is not currently capable of figuring out what the functional interface is that this lambda is implementing. Therefore, it does not know what the type of position is, therefore, the call groupModelList.get(position) does not work; int is required, but the type of position is 'I do not know yet; I cannot know until I know what functional interface this lambda is trying to implementation and for some reason I can't know that right now'. Which isn't int, so you get that error.
one trivial fix is to be explicit. Make that (int position) -> { ... } instead. This may then lead you to the real error you're interested in. For example, if you haven't imported GroupAdapter, this would happen.

Related

What is the difference between a constructor and a builder when using generics?

While programming in Java, I encountered the following problem.
when use Constructor: The following code works fine.
public class Generics<T> {
private T data;
public static <T> Generics<T> of(T data) {
return new Generics<>(data);
}
public Generics(T data) {
this.data = data;
}
}
when use builder: An error occurs saying that the Object type is provided as follows.
I used a builder provided by Project Lombok.
Why doesn't the builder generic in the code above work?
Evidently Lombok generates a static generic builder() method. You can specify the generic type of a generic static method using <T> before the method name, as in:
return Generics.<T>builder()
.data(data)
.build();
If you don't specify the generic type when you call builder(), you get a raw type, at which point generic type inference no longer works.
You need to explicitly add the generics: return Generics.<T>builder() - add that <T> and all will be well.
Explanation
Java is aggressively typed: Every expression and just about every part of an expression has an actual type; java does not allow things to remain in limbo until later; there's no such thing as 'an intermediate - eh, we'll see where it goes'.
That means Generics.builder(), as an expression, needs to be typed by the system. The builder class needs that <T> just the same (it's a Generics.GenericsBuilder<X> - where Builder is a static inner class of Generics, and is defined as public static class GenericsBuilder<X>.
Java cannot just jump to the conclusion that you intend for X and T to be the same type.
Looking ahead, it can figure out that X should be T 'automatically', without your involvement: It can either check the .data(data) invocation, given that the data method is defined in the builder as:
public GenericsBuilder<X> data(X data)
thus, whatever type data (the variable)might be (it'sThere, given that it's the parameter defined asT data`), and therefore, java can conclude that the X should be T.
Otherwise, java can look even further ahead, to build(), and notice that this returns X, and is being returned by a method whose return type is defined as T, thus also giving java the opportunity to say: Ah, X == T, right.
But that is not how java works. In large part because even figuring out what the .data method might mean is rather hard to do when the X of that builder you just made (the X in the declaration public static <X> Generics.GenericsBuilder<X> builder()) must be left in some sort of unknown limbo state for a while as the parser carries on with trying to figure out what the rest means. Given that java allows method overloading (2 different methods with the same name and the same number of params, but different param types, which could contain generics to boot) - it'd be a combinatorial explosion and means you can write java code that takes literally years to parse.
Hence, java does not work that way, it must determine what X is supposed to be solely from the expression Generics.builder(), and it clearly cant.
The solution is to just write it explicitly, using this somewhat exotic syntax: Generics.<T>builder().

Check type of Predicate generic

I'm having 2 classes, their internals doesn't matter at all.
class ClassA {
//...
}
class ClassB {
//...
}
And I'm having 2 predicates that use those classes, let's say they look like this
private Predicate<ClassA> classAPredicate() {
return Objects::nonNull;
}
private Predicate<ClassB> classBPredicate() {
return Objects::nonNull;
}
Now, I'm having generic method in external library that is already beeing used by many users and unfortunatelly, it has pretty generic input parameter which is Object which in 90% of cases is Predicate.
What I need to do, is to extend this method functionality by checking type of passed Predicate and based on that, perform some operations.
public void test(Object obj) {
Predicate predicate = (Predicate)obj;
if(predicate.getClass().isAssignableFrom(ClassA.class)) {
System.out.println(predicate.test(new ClassA()));
// logic specific to Predicate<ClassA>
} else {
System.out.println(predicate.test(new ClassB()));
// logic specific to Predicate<ClassB>
}
}
But, during tests I'm passing both Predicates and it fails with Exception in thread "main" java.lang.ClassCastException:
test(classAPredicate());
test(classBPredicate());
I've been debugging and isAssignableFrom() is always returning false so the error is obvious here. I'm not sure if that is the right approach, but I didn't came up with anything else yet. Is there any way to check what is the type of that Predicate?
I know that what I'm trying to implement isn't ideal, but that is current requirement...
In the above, the predicate class is not assignable from Class A.
if(predicate.getClass().isAssignableFrom(ClassA.class))
This causes the else condition to run which passes an instance of B to the Predicate for type A which causes a cast exception. Due to type erasure, it will not be easy to resolve whether an instance of A or B should be passed to the predicate. 3 options are:
Try each input type until one doesn't throw a ClassCastException.
Handle the expected behavior in a new method instead of the existing test function.
Define a more specific interface than Predicate which also has a method to get the type the predicate tests and use the test type in the condition instead. Ex:
public interface TypedPredicate<T> extends Predicate<T> { Class<T> getTestType(); }
Well,
I have been doing Java Generics for going on three years now. I can cite a dozen Stack Overflow posts about "Reifying Java Generics" here: SO1, SO2, SO3. Most importantly, if you are intending to write Java for years and years, you must know that the "Generic Type Parameter" are simply NOT ACCESSIBLE at Run-Time without fields, or extra methods to retrieve them. Java Generics (The syntax that looks like: STUFF<TYPE> with the greater-than, less-than symbols is STRICTLY A COMPILE-TIME FEATURE). At RunTime, the JRE simply has no idea what the Type of the Type-Parameter is - and all it can do is throw ClassCastException if an attempt to misuse occurs.
NOTE: 'Misuse' the generic type such that it throws ClassCastException should sound odd if you are thinking that the JRE does not know and does not care what the type of the type parameter is. Mostly, the way exceptions are thrown, is such that if the code you write inside of a generic makes presumptions, and if it has made faulty presumptions, then this exception will throw.
Read Sun / Oracle's "To Do" list about "Reifying Generic Type Parameters." Also, most importantly, this concept has a very real name that you should read about all the time in Java - and it is called "Run Time Type Erasure" The solution posted before this Stack Overflow Answer says to use try-catch (ClassCastException) blocks, which is, actually, a valid answer.
ALSO: The answer about creating this type of TypedPredicate<T> extends Predicate<T> is not the correct answer if you intend to use your TypedPredicate<T> in any way that expects to allow Java Lambda Syntax to work with it. When you add the following method:
public interface TypedPredicate extends Predicate { Class
getTestType(); }
You will not be able to use the syntax #FunctionalInterface - which is one of the primary benefits of the class java.util.function.Predicate<T> Furthermore, there is a more severe problem in that, the Type of T is not accessible to the programmer and is not known at RunTime by the JRE
You see this part right here (since the answer has a green check mark):
{ Class<T> getTestType(); }
// Can you answer what you would write inside the method body of this
// 'extra-method' that you have added to Predicate<T> ???
The following implementation of a class that extends "Predicate" cannot be instantiated without a constructor. It cannot be called a "#FunctionalInterface" and lambda-expression cannot be used to create them:
// #FunctionalInterface (Commented Out)
public class TypedPredicate<A> implements Predicate<A>
{
public boolean test(A a) { return pred.test(a); }
// This is how the "Class of A" becomes accessible. It this
// version it is a public (and final) field.
public final Class<A> className;
// NOTE: This is the most important part here, the class of
// Variable-Type Parameter 'A' must be passed as a parameter
// to the constructor. The programmer *LITERALLY* has to tell
// the code what type 'A' actually is! This is the *BANE* of
// what I call the Java-Erasure-Fiasco programming.
public TypedPredicate(Predicate<A> pred, Class<A> className)
{
this.pred = pred;
this.className = className;
}
// Again, because a constructor is necessary, this cannot be
// called a "Functional Interface" and it will not work very
// much like a java.util.function.Predicate<T>, but it will
// indeed implement the interface.
}
The best solution would realign whatever logic you have such that you do not need to guess what type a Predicate is! The next best thing would be to try the catch (ClassCastException) version that was suggested in the previous answer.
FINALLY: This idea regarding the java.lang.Class.isAssignableFrom(...) has the right idea behind it - but only if you actually have the Class<T> clazz as an instance in front of you, so to speak. The only way to get an instance of Class<T> would be to pass it to a constructor as in the example I have posted.

Passing Methods in Java

I'm trying to accomplish passing a method in Java.
Here is the birds-eye-view of what I'm trying to do as a dummy example:
public final class A {
private String value;
public A(String value) {
this.value = value;
}
public final Object bind(Function<String, String> func) {
this.value = func.apply(value);
return this;
}
// Rest of the logic here to deal with `value`
}
public final class B {
public static void main(String[] args) {
A<T> a = new A("hello");
a.bind(B::methodOne).bind(B::methodTwo);
}
private String methodOne(String s) {
// method logic here
return "haha";
}
private String methodTwo(String s) {
// method logic here
return "hi";
}
}
So, basically, I've methods in a class, B in the above example, and I want to pass the methods of B to A and store the return value of that method of B on A for further processing.
I've tried to make use of method reference feature of Java but since I don't code daily with Java, I'm having a hard time getting my head around how to properly accomplish this while fulfilling the constraints above.
Currently, I'm getting a incompatible types: invalid method reference error while I do the binding in the main method.
Update
Made changes on my constraints of the program.
EDIT: The asker updated their question a lot after reading this answer. Crucially, originally each method had a completely different signature (different param types and amounts, and different return types). I'm leaving this answer untouched, be aware it is no longer particularly relevant to the question as it currently stands.
This doesn't work well because the methods you want to pass have completely different signatures (methodOne's is (B, String) -> int (why do you have a capital I Int in there, is that a typo?), methodTwo is (B) -> String, and methodThree is (B, String, String) -> String.
In java lambdas must fit a functional interface. It is not possible to have a functional interface for a variable number of input arguments.
With generics you can attempt to paper over the fact that the types of your inputs and output are different every time.
This really sounds like an X/Y problem: You have problem X (which you didn't explain and we don't know what it is), and you thought: I know! I'll use lambdas to abstract away the notion of 'a method'... and now you're asking questions about that.
But you're asking the wrong question. Ask X. Because even if hypothetically you could somehow fit your 3 methods all in the same lambda type (you can't), you would not then be able to invoke them.
Here's one more workable notion, but I have no idea if it solves your X because you didn't explain this:
#FunctionalInterface
public interface MyXThinger {
Object result(Object... args);
}
If you want to invoke this, how would you know that the particular MyXThinger (you didn't explain what X is, so I can't come up with a good name here) works if you pass 2 strings, and crashes if you pass anything else? That's.. more or less why I find your problem description insufficient to give solid advice here.
You're writing the expression B::methodOne in a static context.
non-static methods have an invisible parameter, called 'the receiver': It's the instance.
So, in a static context, B::methodOne has the signature: (B, String) -> String. What your bind method wants is (String) -> String, and these two are not compatible. Therefore, this does not work.
There are two ways to fix it:
create an instance: B b = new B(); a.bind(b::methodOne);. The expression b::methodOne, where b is a variable of type B referencing an actual instance of B (as created with new B()) DOES have the signature (String) -> String as required.
Make the methodOne method static, at which point it no longer has the invisible B instance parameter.
Your code is also littered with rookie mistakes; you must call a.bind and not A.bind, using A and B as class names is extremely confusing, your bind method returns Object (it should return A), etc. The way to fix those is to learn basic java, I think; trying to tackle those mistakes bit by bit seems unsuitable for what stackoverflow is for. Thus, I leave those as an exercise for you.

Can you explain why the first unwrapped method reference does not compile?

In this example, passing a method reference to Stream.of does not work but once it's wrapped it works. I can't quite get my head around why this is. Isn't the method reference equivalent to the functional interface?
public class A {
String a() {
return "";
}
void b() {
Stream.of(this::a); // won't compile
Stream.of(wrap(this::a)); // will compile
}
static <T> Supplier<T> wrap(Supplier<T> f) {
return f;
}
}
Stream.of has the following signature:
public static<T> Stream<T> of(T t)
The following example will compile because you explicitly providing a type information for T.
Stream<Supplier<String>> a = Stream.of(this::a);
The first example Stream.of(this::a); equivalent to:
Object a = this::a;
where Object is not a functional interface and will not compile.
Providing with a functional interface this example compiles:
Runnable a = this::a;
Stream.of(a);
In the second example, wrap provides a functional interface Supplier
Stream.of(T) expects an Object and you pass to it a method reference in the first statement. But an Object parameter is not a functional interface, so it cannot accept a method reference or a lambda that is not specifically typed.
With lambda, it would produce also an error : Stream.of(()->this.a()).
A simpler example could be Stream.of(()-> "foo") that will just not compile.
But if you type the method reference or the lambda it works :
Stream.of((Supplier<String>) this::a)
or
Stream.of((Supplier<String>) () -> this.a())
In the working statement you pass to Stream.of(T) a parameter that is a Supplier<String>. That refers to a functional interface but that is typed as in the previous working examples, so it is valid as parameter that expects an Object.
this::a is contextless and could mean different things. You need to provide some context to help the compiler to figure out what you actually meant by this::a.
Stream.<Supplier<String>>of(this::a);
Though, that Stream<Supplier<String>> doesn't seem to be what you wanted. If you need a Stream<String>, use Stream.generate: no extra type information needed since the method takes a Supplier<T> (no ambiguity here).
Stream.generate(this::a);
On a side note, both statements expect you to save their results into variables. Defining variables of the right type often facilitates resolving such issues.
Stream<Supplier<String>> s1 = Stream.of(this::a);
Stream<String> s2 = Stream.generate(this::a);
All credit to #J-Alex and #Holger for their precious comments.

Can I work with generic types from a calling class?

I'm currently brushing up my Java and reading up on Generics. Since they were not treated extensively in my Java class, I'm still having some trouble wrapping my mind about it, so please keep that in mind when answering.
First of all, I'm pretty sure that what I'm trying to is not possible. However, I'd like to find out where my thinking is wrong and how I should go about achieving what I want.
What I'm trying to do is manipulating an object that implements a generic interface from another class that has no knowledge about the instantiated type. Thus, I have something like the following classes:
public interface CalledInterface<E> {
public E get() { ... }
public set(E e) { ... }
}
public class Called implements CalledInterface<String> {
...
}
Now what I want to do is:
public class Caller {
protected CalledInterface<?> c;
public Caller (CalledInterface<?> arg) {
c = arg;
}
public void run(){
// I can do this:
c.set(c.get());
// But I'd want to be able to do something like:
<?> element = c.get();
c.set(element);
}
}
What is the fundamental flaw in my thinking, if there is one? And what approach should I rather be taking?
First of all, keep in mind that generics is a compile time thing not a runtime.
Now in your Caller you defined Called c. Called is defined to implement CalledInterface<String>, so automatically, Called has the following methods generated at compile time:
String get();
void set(String e); //i assume you wanted to return void
So essentially this doesn't really make sense:
<?> element = c.get();
The Caller class isn't even aware Called is using generics internally, for it, Called just deals with strings.
UPDATE
Based on your comment, since you don't want Caller to use Called directly but use CalledInterface first thing you have to do is change the type of c to that. In this case you should not use generics, because the whole point of generics is that the same class is used in different scenarios with different types (again determined at compile time), enforcing types without having repeated code.
If I understand correctly you don't want to restrict Caller to use String, so what you have to do is change CalledInterface to not use generics, and change the methods to:
Object get();
void set(Object o);
This is how we used to do things before Generics in Java 1.4. You obviously run the risk of not having type safety, so think through whether what you want really makes design sense, because it probably does not because you have to do instanceof anyway to check the type to use the Object in a useful way (i.e. to access its methods).
If on the other hand you just change the c member (and the constructor argument of Caller) to:
CalledInterface<String> c;
Your Caller will be interacting with the CalledInterface rather than the implementation and at the same time still be type safe. So you can still pass an instance of Called and set it to c.
After your edit:
// I can do this:
c.set(c.get());
No you can't. It won't compile with c being CalledInterface<?>. (Have you even tried it?)
To do this, you can use a "capture helper":
private static <T> void helper(CalledInterface<T> c) {
c.set(c.get());
}
public void run(){
helper(c);
}
Which also solves your second problem:
private static <T> void helper(CalledInterface<T> c) {
T element = c.get();
c.set(element);
}
public void run(){
helper(c);
}
There are a few minor mistakes in your code:
protected Called c;
public Caller (CalledInterface arg) {
c = arg;
}
You are not allowed to assign arg here, because the type CalledInterface is not a subtype of Called (it is the other way around)
Also you should give type information when using CalledInterface (it is allowed to leave it out, but only for legacy purposes).
Now to the part you are wondering about. For the type Called, the compiler knows get() returns a String, if you are not interested in that, you can of course always use Object as the type of element. The compiler also knows that set() takes a String as argument, so it requires you to give one. In generics is essentially the same as using Object in a case without generics (even though it isn't allowed on the location you use it, because it doesn't make sense). This means that you would be telling the compiler to forget the type on the first line (calling get()) and to unforget it on the line below.

Categories

Resources