Page 1 of 1
[HD Pg 0, Sec. 12.5.1 - lambda-expressions]
Posted: Sat Dec 01, 2018 1:52 pm
by flex567
I am trying to expand the code from the book(Car example) from Lambda exression to how compiler sees it but I don't exactly how.
What is missing in my code? See the code snippet and my coments.
Code: Select all
import java.util.ArrayList;
import java.util.List;
public class TestClass {
public static void main( String[] args) {
//No Lambda expression
// CarMall cm = new CarMall();
// CarFilter cf = new CompanyFilter(" Honda");
// List<Car> carsByCompany = cm.showCars(cf);
//
// System.out.println( carsByCompany);
//Lambda Expression
// CarMall cm = new CarMall();
// List < Car > carsByCompany = cm.showCars( c -> c.company.equals(" Honda"));
// System.out.println( carsByCompany);
//How compiler sees it
CarMall cm = new CarMall();
List <Car> carsByCompany = cm.showCars( new XYZ().showCar()); // I am not sure about this snippet ???
System.out.println( carsByCompany);
}
}
class Car {
String company;
int year;
double price;
String type;
Car( String c, int y, double p, String t){
this.company = c;
this.year = y;
this.price = p;
this.type = t;
}
public String toString(){ return "(" + company +" "+ year +")"; }
}
class CarMall {
List<Car> cars = new ArrayList< >();
CarMall() {
cars.add(new Car(" Honda", 2012, 9000.0, "HATCH"));
cars.add(new Car(" Honda", 2018, 17000.0, "SEDAN"));
cars.add( new Car(" Toyota", 2014, 19000.0, "SUV"));
cars.add( new Car(" Ford", 2014, 13000.0, "SPORTS"));
cars.add( new Car(" Nissan", 2017, 8000.0, "SUV"));
}
List <Car> showCars( CarFilter cf){
ArrayList <Car> carsToShow = new ArrayList < >();
for( Car c : cars){
if( cf.showCar(c))
carsToShow.add( c);
}
return carsToShow;
}
}
interface CarFilter {
boolean showCar( Car c);
}
//class CompanyFilter implements CarFilter {
// private String company;
// public CompanyFilter( String c){
// this.company = c;
// }
// public boolean showCar( Car c){
// return company.equals(c.company);
// }
//}
class XYZ implements CarFilter {
public boolean showCar(Car c) {
return c.company.equals(" Honda");
}
}
Re: [HD Pg 0, Sec. 12.5.1 - lambda-expressions]
Posted: Sat Dec 01, 2018 10:51 pm
by admin
> List <Car> carsByCompany = cm.showCars( new XYZ().showCar()); // I am not sure about this snippet ???
Why are you calling .showCar() on XYZ object?
The cm.showCars method expects a CarFilter object. XYZ implements CarFilter and so, new XYZ() is a valid CarFilter object. This is all that you need to pass to cm.showCars. i.e.:
List <Car> carsByCompany = cm.showCars( new XYZ() ); //remove .showCar()
If you look at the code for CarMall's showCar method, you will see that it invokes showCar on the CarFilter object that was passed to this method.
Re: [HD Pg 0, Sec. 12.5.1 - lambda-expressions]
Posted: Sun Dec 02, 2018 11:40 am
by flex567
Aha I think I understad this example.
Re: [HD Pg 0, Sec. 12.5.1 - lambda-expressions]
Posted: Sun Feb 24, 2019 8:58 am
by flex567
Can it be said that lambda expression return a reference of an object that implements the method in a way that is implemented in lambda expression?
In case of this is certainly the case:
Code: Select all
List<Car> carsByCompany = cm.showCars(c -> c.company.equals("Honda"));
returns a reference of an object
Re: [HD Pg 0, Sec. 12.5.1 - lambda-expressions]
Posted: Sun Feb 24, 2019 11:17 am
by admin
Yes, that is correct. The code c.company.equals("Honda") goes in the method of the class generated by the compiler.
Re: [HD Pg 0, Sec. 12.5.1 - lambda-expressions]
Posted: Sun Feb 24, 2019 4:10 pm
by flex567
So that means that this works:
Code: Select all
Object o = c -> c.company.equals("Honda");
And this as well:
?
Re: [HD Pg 0, Sec. 12.5.1 - lambda-expressions]
Posted: Sun Feb 24, 2019 7:38 pm
by admin
What happend when you tried it out?
Also, how will the compiler know what interface should the class implement. You need to read this topic from the book again thoroughly.
Re: [HD Pg 0, Sec. 12.5.1 - lambda-expressions]
Posted: Tue Apr 30, 2019 2:31 pm
by OCAJO1
The code (whether using lambda shortcut or not) with the CarMall class, is an example of creating a Factory Pattern using an Interface (rather than abstract class), Isn't it?
Also,
As an exercise, try to expand the lambda expression x ->x.price>10000 into a class that implements CarFilter.
Is there a good way to capture the price form Cars List for comparison to 10000, so don't have to rewrite the priceFilter call from main() for each price?
Thanks
Re: [HD Pg 0, Sec. 12.5.1 - lambda-expressions]
Posted: Tue Apr 30, 2019 8:38 pm
by admin
1. No, it is not an example of factory pattern.
2. Not sure what you are trying to do.
Re: [HD Pg 0, Sec. 12.5.1 - lambda-expressions]
Posted: Wed May 01, 2019 12:29 pm
by OCAJO1
1. Hah! It is not, because in CarMall() method different car records have been added, not chosen and returned from different car classes based on the user's choice?
2. Since the prices of the cars are already known in CarMall(), I was going to take the comparison out of the PriceFilter class (code below) and just a have enhanced for loop in the main() that checks the price in each record in CarMall() to see if > 10000, so for example 19000.0 can be replaced with a variable holding the price of the car that is > 10000 in main() method's PriceFilter pf = new PriceFilter(19000.0);
Code: Select all
class PriceFilter implements CarFilter{
private double price;
public PriceFilter(double p){
this.price = p;
}
@Override
public boolean showCar(Car c){
if (this.price > 10000)
return this.price == c.price;
else
return false;
}
}
Re: [HD Pg 0, Sec. 12.5.1 - lambda-expressions]
Posted: Wed May 01, 2019 1:36 pm
by admin
1. yes but you will need to read more about the pattern.
2. ok. sounds good.
Re: [HD Pg 0, Sec. 12.5.1 - lambda-expressions]
Posted: Wed May 01, 2019 2:51 pm
by OCAJO1
1. Ok.
2. But, I'm still wondering about my original question
Is there a good way to capture the price from Cars List for comparison to 10000, so don't have to rewrite the priceFilter call from main() for each price?
Thanks
Re: [HD Pg 0, Sec. 12.5.1 - lambda-expressions]
Posted: Wed May 01, 2019 6:42 pm
by admin
Well, that is the reason there is Predicate. You can pass a Predicate to car filter and use a lambda to implement that predicate.
Re: [HD Pg 0, Sec. 12.5.1 - lambda-expressions]
Posted: Wed May 01, 2019 6:56 pm
by OCAJO1
Good thing we're not still dealing with java 7 or earlier

Re: [HD Pg 0, Sec. 12.5.1 - lambda-expressions]
Posted: Thu May 02, 2019 5:09 pm
by OCAJO1
I played around with combining predicates and making use of already existing car records and came up with the code below,
Code: Select all
import java.util.*;
import java.util.function.Predicate;
class Car{
String company; int year; double price; String type;
Car(String c, int y, double p, String t){
this.company = c; this.year = y;
this.price = p; this.type = t;
}
@Override
public String toString() { return "("+company+" "+year+" "+price+")"; }
}
class CarMall {
List<Car> cars = new ArrayList<>();
CarMall(){
cars.add(new Car("Honda", 2012, 9000.0, "HATCH"));
cars.add(new Car("Honda", 2018, 17000.0, "SEDAN"));
cars.add(new Car("Toyota", 2014, 19000.0, "SUV"));
cars.add(new Car("Ford", 2014, 13000.0, "SPORTS"));
cars.add(new Car("Nissan", 2017, 8000.0, "SUV"));
}
List<Car> showCars(Predicate<Car> cf, Predicate<Car> cp, Car c){
ArrayList<Car> carsToShow = new ArrayList<>();
Predicate<Car> cfp = cf.and(cp);
if(cfp.test(c)) carsToShow.add(c);
//this code will show all the cars, except for the ones requested
//if(!cfp.test(c)) carsToShow.add(c);
return carsToShow;
}
}
public class TestClass{
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
CarMall cm = new CarMall();
for (Car v : cm.cars){
List<Car> carsByCompany = cm.showCars(c -> c.company.equals(v.company),
c -> c.price > 10000.0,
v);
if (!carsByCompany.isEmpty()) System.out.println(carsByCompany);
}
}
Question: Given the original version in the book vs. this one, OOP-wise speaking, is one better than the other or each do their own thing?
Thanks
Re: [HD Pg 0, Sec. 12.5.1 - lambda-expressions]
Posted: Thu May 02, 2019 8:28 pm
by admin
This loop for (Car v : cm.cars){ should be inside showcars method, not in main.
Re: [HD Pg 0, Sec. 12.5.1 - lambda-expressions]
Posted: Fri May 03, 2019 12:08 pm
by OCAJO1
But the whole idea of doing it this way was so didn't have to call the showCars method from main() with one hard coded car name after another to check against the price boundary.
Wait a sec., the fact that the user is only providing a price boundary - the requirements have changed. I think I'll create a showCars2 method in carMall class so the user (TestCalss main()) can provide the price boundary to this method and within the method the loop go through the car records checking against the price.
Something like this,
Code: Select all
List<Car> showCars2(Predicate<Car> cp){
ArrayList<Car> carsToShow = new ArrayList<>();
for (Car c : cars){
Predicate<Car> cf = d->d.company.equals(c.company);
Predicate<Car> cfp = cf.and(cp);
if(cfp.test(c)) carsToShow.add(c);
//this code will show all the cars, except for the ones requested
//if(!cfp.test(c)) carsToShow.add(c);
}
return carsToShow;
}
This is the call from TestCalss' main()
Code: Select all
List<Car> carsByCompany2 = cm.showCars2(c->c.price>10000);
if (!carsByCompany2.isEmpty()) System.out.println(carsByCompany2);
What do you think?
Re: [HD Pg 0, Sec. 12.5.1 - lambda-expressions]
Posted: Fri May 03, 2019 5:16 pm
by admin
Yes, better.
Re: [HD Pg 0, Sec. 12.5.1 - lambda-expressions]
Posted: Sat May 04, 2019 3:13 pm
by OCAJO1
I took another quick look at it and there is really no reason to call the new method showCars2. Overloading the original showCars method will do the job.
Re: [HD Pg 0, Sec. 12.5.1 - lambda-expressions]
Posted: Tue Oct 15, 2019 5:39 pm
by DazedTurtle
Feedback: Maybe I'm just tired, but having similar names for two entirely different methods is throwing me off. I keep having to flip back to the previous pages to see which one is "showCars" and which one is "showCar." It'd help if the interface one was called filterCar or something.
I admit, I'm guilty of using similar names in my own code, but dealing with it when I'm working on it and came up with the names myself is very different from dealing with it while I'm learning about a new concept.
Re: [HD Pg 0, Sec. 12.5.1 - lambda-expressions]
Posted: Tue Oct 15, 2019 10:36 pm
by admin
Sure, thank you for your feedback. Passed on to the author.