Page 1 of 1

About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Fri Sep 09, 2016 11:02 pm
by Hissam

Code: Select all

import java.util.*;
class Data{
    int value;
    public Data(int x){ this.value = x; }
    public String toString(){ return ""+value; }
}

class MyFilter {
  public boolean test(Data d){
     return d.value == 0;
  }
}

public class TestClass{
    
   public static void filterData(ArrayList<Data> dataList, MyFilter f){
      Iterator<Data> i = dataList.iterator();
      while(i.hasNext()){
           if(f.test(i.next())){
                i.remove();
           }
       }
   }

  public static void main(String[] args) {
        ArrayList<Data> al = new ArrayList<Data>();
        Data d = new Data(1); al.add(d);
        d = new Data(2); al.add(d);
        d = new Data(0); al.add(d);

        filterData(al, new MyFilter());  //1 

        System.out.println(al);
    }
}
How can you use a lambda expression to achieve the same result?

========================================================
Add implements java.util.function.Predicate<Data> to MyFilter definition and replace the line at //1 with:
filterData(al, x -> x.value==0);


this is correct answer, it showing as wrong.

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Sat Sep 10, 2016 1:23 am
by admin
Which option number are you talking about?

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Sat Nov 25, 2017 4:15 pm
by Rinkesh
I am not able to understand the entire question as well as why the answer was the last option and can you tell me the output of the last option??

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Sun Nov 26, 2017 12:27 am
by admin
What happened when you tried running the given code and with the changes suggested in the last option? What output did you get in both the cases?

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Mon Jul 09, 2018 12:26 am
by naziat
during iteration you are removing elements from List, dont you think it will throw ConcurrentModificationException.

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Mon Jul 09, 2018 1:06 am
by admin
naziat wrote:
Mon Jul 09, 2018 12:26 am
during iteration you are removing elements from List, dont you think it will throw ConcurrentModificationException.
No, you are allowed to remove items using Iterator's remove method while iterating. You should try out the code.

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Sat May 04, 2019 5:04 pm
by Mark7777
I'm back. And I'm plagued by a recurring dumb question. I was under the impression that in order for an interface to be used it had to be implemented by a class, generally speaking. What class implements the Predicate interface here? I really struggle with lambdas, and I have a great book.

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Sat May 04, 2019 9:49 pm
by admin
An anonynous class generated by the compiler implements the Predicate interface.
Which book are you following?

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Sat May 04, 2019 11:50 pm
by Mark7777
Thanks, Paul. That really helps. I have the OCA 8 Boyarsky-Selikoff book, and Java 8 in Action by Urma et al. The answer is probably buried in there somewhere but I didn't find it. Part of my problem is conceptualizing how the lambda goes from the call to the test method.

In my mind I pretend it's placed inside f, and then that gets transferred to a non-existent body of test() {}. So it looks something like this behind the scenes:

Code: Select all

public class TestClass{         
     public static void filterData(ArrayList<Data> dataList, java.util.function.Predicate<Data> f){      
           Iterator<Data> i = dataList.iterator();      
           while(i.hasNext()){           
           if(f.test(i.next())){ 
           boolean  b = x.value == 0; // the lambda
          return b; // more lambda
                      
 }        
}    
}
But that obviously doesn't work and is a mangled mess. The iterator complicates it, but the gist I think is that I'm providing the test() body { } with the lambda code that returns a boolean.

As for the lambda itself, I also can't figure out where the x comes from and why. filterData(al, x -> x.value==0); The only x I see is the int var in the Data object, but that can't be it. I've seen the same problem in other code, like in Selikoff's book. The reference variable (like the x) just materializes and I can't figure out from where. al refers to the ArrayList, but what object does x refer to and where is that thing? No doubt it's right in front of me.

FYI, I passed OCA 7 and was close to taking OCP 7 when something came up and I couldn't get to the exam before they retired it. So I'm sort of starting over with OCA 8. Fun.

Mark

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Sat May 04, 2019 11:59 pm
by admin
You might want to go through this short primer on lambda: https://enthuware.com/lambda-for-ocajp
and may be OCAJP Fundamentals by Hanumant Deshmukh if you need more details.

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Sun May 05, 2019 1:13 pm
by Mark7777
Very good and clear tutorial. Recommended. Thank you.

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Thu Aug 08, 2019 3:14 am
by Bhaskar
I have understood the lambda expression part, but i have a doubt regarding the following code:

Code: Select all

ArrayList<Data> al = new ArrayList<Data>();         
Data d = new Data(1); 
al.add(d);         
d = new Data(2); 
al.add(d);         
d = new Data(0); 
al.add(d); 
When I print the ArrayList object using al.toString(), why does it print [1, 2, 0] and not [0, 0, 0] ? Isn't reference variable d getting pointed to a new object after every insertion to ArrayList and the latest object is "new Data(0)" ? I recon it's something to do with how elements are inserted into arrays, but i am not sure.

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Thu Aug 08, 2019 5:38 am
by admin
Variable d does point to a new object after every add but that has nothing to do with old value of variable d that is already in the list.
You might want to go through a good book to learn how references in Java work before attempting mock exams. Understanding of reference/variable/objects is very important for the exam.

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Mon Jan 11, 2021 9:04 am
by Denyo1986
Hissam wrote:
Fri Sep 09, 2016 11:02 pm

Code: Select all

import java.util.*;
class Data{
    int value;
    public Data(int x){ this.value = x; }
    public String toString(){ return ""+value; }
}

class MyFilter {
  public boolean test(Data d){
     return d.value == 0;
  }
}

public class TestClass{
    
   public static void filterData(ArrayList<Data> dataList, MyFilter f){
      Iterator<Data> i = dataList.iterator();
      while(i.hasNext()){
           if(f.test(i.next())){
                i.remove();
           }
       }
   }

  public static void main(String[] args) {
        ArrayList<Data> al = new ArrayList<Data>();
        Data d = new Data(1); al.add(d);
        d = new Data(2); al.add(d);
        d = new Data(0); al.add(d);

        filterData(al, new MyFilter());  //1 

        System.out.println(al);
    }
}
How can you use a lambda expression to achieve the same result?

========================================================
Add implements java.util.function.Predicate<Data> to MyFilter definition and replace the line at //1 with:
filterData(al, x -> x.value==0);


this is correct answer, it showing as wrong.

I agree with this post. Option 3 seems correct to me as well. The question doesnt say anything about functional interfaces but asks how the same is achieved using lambda expressions. So why is option 3 not correct? It does the same and it uses lambda, or what am I missing?

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Mon Jan 11, 2021 10:57 am
by admin
Did you try applying the changes suggested in option 3 to the existing code and then compiling it?

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Mon Jan 11, 2021 11:14 am
by Denyo1986
Yes, I have.

It gave me the same error explanation (MyFilter is not a functional interface) which I did and still do not understand.

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Mon Jan 11, 2021 11:22 am
by admin
OK, so option 3 is using a lambda expression x -> x.value==0. But this expression can work only if the second parameter to the filterData method is a functional interface, which can be implemented by the expression. The only other change proposed in this option is to make MyFilter implement java.util.function.Predicate<Data>. But that still doesn't make MyFilter a functional interface because it does not have exactly one abstract method (as required by the Predicate interface).

To use a lambda expression, you also need to have a corresponding functional interface.

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Mon Jan 11, 2021 11:27 am
by Denyo1986
So, would we be able to somehow make this work with a class that implements a functional interface and does not have any other methods than the implemented one abstract method derived from the interface or will this never work since it is a class and an INTERFACE is required?

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Mon Jan 11, 2021 10:57 pm
by admin
No, a lambda expression can only be used to implement a functional interface. It has to be an interface. A class or abstract class will not work. This is explained in Section 14.1 page 363 of Deshmukh's OCP Java 11 Part 1 fundamentals book.
Java language designers decided not to allow lambda expressions for abstract classes to reduce complexity. Thus, the only question remaining is which interface should the generated class implement. That depends on the context. The type that the context expects is described as the “target type” and is the interface that the class generated by the compiler must implement.

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Tue Jan 12, 2021 3:18 am
by Denyo1986
OK, thansks a lot.

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Sat Jan 14, 2023 8:05 pm
by thaednevol
Hello you all. I have a question regarding access modifier of value in Data class, what is it and why does it change when the code changes from, for example, java.util.function.Predicate to java.util.function.Predicate<Data>

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Sat Jan 14, 2023 10:42 pm
by admin
The value field in Data class has no access modifier, which means it has package access. It is not impacted/changed by any other code.

>why does it change when the code changes from, for example, java.util.function.Predicate to java.util.function.Predicate<Data>

Sorry, I have no idea what you mean by this. Which code change are you talking about?

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Sun Jan 15, 2023 6:33 pm
by thaednevol
Hello.

If the signature of filterData is

public static void filterData(ArrayList<Data> dataList, java.util.function.Predicate f){ ...

The IDE says : "Cannot resolve symbol 'value'" in filterData(al, x -> x.value==0);

But, if the signature changes to

public static void filterData(ArrayList<Data> dataList, java.util.function.Predicate<Data> f){ ...

It compiles fine, why?

Re: About Question enthuware.ocajp.i.v8.2.1474 :

Posted: Tue Jan 17, 2023 1:29 am
by admin
If your method argument type is java.util.function.Predicate f, then how will the compiler know that there will be a "value" field in Predicate? There is no information present in the code for the compiler to understand that.

If your method argument type is java.util.function.Predicate<Data> f, the compiler knows from the parameterized type Data that x will refer to Data and Data has value.