Win a copy of Modern frontends with htmx this week in the Spring forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

'forEach(java.util.function.Consumer)' in 'java.lang.Iterable' cannot be applied

 
Ranch Hand
Posts: 2925
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I ran a simple lambda example which ran fine. After that I am trying to run it without lambda (using anonymous class). However, it is giving error "'forEach(java.util.function.Consumer)' in 'java.lang.Iterable' cannot be applied to '(anonymous MyInterface)'".




Below is the MyInterface  interface.


How can I resolve this? Thanks.
 
Saloon Keeper
Posts: 10653
85
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
 
Bartender
Posts: 5465
212
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There are a few problems with your code.

First of all, lets simplify the code a little. In your main method, start with

and then you must do:

Second problem is that your List is a List of Objects, and so you get an error, because your interface expects a String to be printed, but instead it gets an Object. In Carey's snippet you see that he uses a List<String>, to remedy this problem.

Third problem is that you define a String as parameter in the display-method of your interface. So if you have a List of, say, Integers, the above will not work. So you could have your interface to be

and then do

and do:

or with a method reference:
 
Saloon Keeper
Posts: 15458
363
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think you guys are missing Monica's point. The goal is to NOT use a lambda expression, but instead replace it completely with an instance of an anonymous class.

Monica, forEach() requires a Consumer. You can't pass it a MyInterface, because MyInterface isn't a Consumer. To pass the forEach() method an instance of an anonymous class, you have to do this:

Note that this requires that you've properly parameterized myList, which you currently haven't.
 
Piet Souris
Bartender
Posts: 5465
212
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Fair enough, but I was concentrating on the 'MyInterface'. So the full story would then become
 
Saloon Keeper
Posts: 27720
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Aside from possibly intellectual curiosity (this is Monica, after all ), I'm not sure about the advantage of using a forEach() method over simply using the general language foreach verb which works on arrays and Iterables. Or a stream, for that matter.
 
Stephan van Hulst
Saloon Keeper
Posts: 15458
363
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The only advantage I see for using forEach() on collections is that it might be more succinct when passing in a method reference or short lambda expression:

In general though, I too prefer the enhanced for-loop, which clearly advertises its non-functional nature. To me, a functional coding style involves pure functions, and forEach() is impure.

There is a clear advantage to using forEach() on streams though. It makes it really easy to perform parallel tasks:
 
Monica Shiralkar
Ranch Hand
Posts: 2925
13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephan van Hulst wrote: To pass the forEach() method an instance of an anonymous class, you have to do this:
,



Thanks.
The accept method of consumer takes the type Object, and not a String. So I took that and did a toString to it . It worked fine.

Here I had to convert object to String using toString method then why is is so that in the lambda code above it was not required to convert to string from object ?


Stephan van Hulst wrote:. You can't pass it a MyInterface,



Ok. So in which case can we pass our own interface to a higher order method ?
 
Master Rancher
Posts: 4764
71
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Monica Shiralkar wrote:Here I had to convert object to String using toString method then why is is so that in the lambda code above it was not required to convert to string from object ?


Stephan previously commented (on the very code you're asking about):

Stephan van Hulst wrote:Note that this requires that you've properly parameterized myList, which you currently haven't.


To spell this out more clearly: you defined myList like this:

Here, you are not using generics at all.  You presumably got a warning like "raw use of parameterized class ArrayList", which you ignored.  This is generally a bad practice - you should provide parameters for classes like this.   In this case, it seems like all the things you're putting in the list are Strings, so it seems sensible to say it's an ArrayList of Strings:

Now you will find that in subsequent code, you don't need to do things like convert an Object to a String, because the compiler already knows you have a list of Strings.  That's what Stephan means by properly parameterizing myList.

You can also declare it as a List<Object> if you want:

In that case you might later have to call toString() if you need a String from it.  But at least in that case, you've made a conscious choice to treat myList as a List of Objects.

Monica Shiralkar wrote:Ok. So in which case can we pass our own interface to a higher order method ?


You can pass an instance of your own MyInterface to any method that accepts a MyInterface, or to any method that accepts a supertype of MyInterface.  From your definition of MyInterface, it doesn't implement or extend anything else... so the only other valid supertype would be Object.  In this thread, the method you were trying to use was forEach() which takes a type of Consumer.  Since MyInterface doesn't implement Consumer, you can't use the method.  If you make MyInterface implement Consumer, you can.

Now the confusing thing here is that if you were using a lambda expression here, not an interface, then the rules for that are much looser, and the compiler will let you write something like

where it will figure out that since forEach takes a Consumer, and Consumer only has one method, then your "a -> System.out.println(a)" must be intended to be an implementation of that method - so it will convert the lambda expression to act like an instance of Consumer for this method call, without you having to explain that to the compiler somehow.  

Why do we get this flexibility for a lambda, but not for an anonymous class implementing an interface?  Well, mostly because lambdas came to Java later on, long after interfaces.  In the beginning Java was designed to be pickier and to force you to make sure you were using the right type for everything... often in the most verbost way possible.  Nowadays, they are more likely to design a feature to be a little more flexible, and not require you to declare things that it can infer on its own.  If they were designing the language from scratch, it might well be done differently.  But instead, we just have to accept that the rules evolved they way the rules evolved.
 
Sheriff
Posts: 22780
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Piet Souris wrote:Fair enough, but I was concentrating on the 'MyInterface'. So the full story would then become


That can be done a bit simpler using a method reference:

You don't even need an existing interface for that:

(Of course all of this is a lot more complex than just myList.forEach(a -> System.out.println(a)) or myList.forEach(System.out::println))
 
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Another solution, using default method display():
 
Marshal
Posts: 79082
376
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Apart from the bad indentation: that trick would work. It does seem overkill, however, to extend that interface to add a method. What would happen if you added that method to the anonymous class?
 
Fikri Harlov
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:It does seem overkill, however, to extend that interface to add a method. What would happen if you added that method to the anonymous class?



She wants to pass MyInterface to a forEach(), but it is not a Consumer.

If method display() contains 20 lines source code, it will be ugly to be in the forEach()

In MyInterface we can put many more default methods that will be more beautiful to be outside the forEach().
 
Campbell Ritchie
Marshal
Posts: 79082
376
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Fikri Harlov wrote:. . . If method display() contains 20 lines source code, it will be ugly to be in the forEach() . . .

There is a lot more to it than that. Have you tried it yourself?
 
Fikri Harlov
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If the display() method is in the anonymous class, I can't reuse it anywhere else in the program.
 
Campbell Ritchie
Marshal
Posts: 79082
376
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You can't reuse it anywhere from that interface anyway; it would only compile with private access when I tried it.

[edit]Sorry, I said interface when I should have said anonymous class.
 
Campbell Ritchie
Marshal
Posts: 79082
376
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Nobody ever liked anonymous classes anyway, and nobody shed any tears when many of them were replaced by λs.
 
Fikri Harlov
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Reusing display() method.
 
Fikri Harlov
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Nobody ever liked anonymous classes anyway, . . .


In forEach() I use an anonymous class that implements MyInterface. Anonymous classes are a very good thing.
 
Mike Simmons
Master Rancher
Posts: 4764
71
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, if you like anonymous classes, then you like them.  And "no one ever liked them" is an overstatement.  But... when was the last time you used an anonymous class for something that couldn't be done more easily with a lambda?  I'm sure that such situations exists.  But how often does it come up, really?
 
Fikri Harlov
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Whenever I need a class with fields rather than a simple function like a lambda.
 
Carey Brown
Saloon Keeper
Posts: 10653
85
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
 
Campbell Ritchie
Marshal
Posts: 79082
376
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:. . . an overstatement.

To quote Carey,



touché!

But... when was the last time you used an anonymous class for something that couldn't be done more easily with a lambda? . . .

When I wanted to show how you can convert an anonymous class to a λ or a method reference!
 
Carey Brown
Saloon Keeper
Posts: 10653
85
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Although... I was trying to find an example in my source code archive and only came up with examples like this. This was NOT implemented as an ANONYMOUS class because the constructor takes a parameter so it could be used in more than one place.

 
Carey Brown
Saloon Keeper
Posts: 10653
85
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Fikri Harlov wrote:Whenever I need a class with fields rather than a simple function like a lambda.


@Fikri, I think you may have a valid point but I'm having a hard time coming up with a legitimate example. Could you please provide one?
 
Carey Brown
Saloon Keeper
Posts: 10653
85
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This might be an example of an anonymous class with a field, though it also has a lambda feature.
 
Fikri Harlov
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I refactor your code, eliminating unnecessary things.
 
Fikri Harlov
Greenhorn
Posts: 10
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I use an anonymous class in the generate() method, not Lambda.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic