Programmer I Chapter 6: Lambdas and Functional Interfaces Flashcards
in what order (asc, desc) would these sort?
Comparator strings = (s1, s2) -> s2.compareTo(s1);
Comparator moreStrings = (s1, s2) -> - s1.compareTo(s2);
Both of these comparators actually do the same thing: sort in descending order. In the first example, the call to compareTo() is“backwards,” making it descending. In the second example, the calluses the default order; however, it applies a negative sign to the result,which reverses it
Can you figure out the type of x?
public void whatAmI() {
consume((var x) -> System.out.print(x), 123);
}
public void consume(Consumer < Integer > c, int num) {
c.accept(num);
}
If you guessed Integer, you were right. The whatAmI() method creates a lambda to be passed to the consume() method. Since the consume()method expects an Integer as the generic, we know that is what the inferred type of x will be.
What do you think the type of x is here?
public void counts(List< Integer > list) {
list.sort((var x, var y) -> x.compareTo(y));
}
The answer is Integer. Since we are sorting a list, we can use the type of the list to determine the type of the lambda parameter.
Do you see what’s wrong here?
(a, b) -> { int a = 0; return 5;} // DOES NOT COMPILE
We tried to redeclare a, which is not allowed. Java doesn’t let you create a local variable with the same name as one already declared in that scope.
How many syntax errors do you see in this method?
11: public void variables(int a) {
12: int b = 1;
13: Predicate p1 = a -> {
14: int b = 0;
15: int c = 0;
16: return b == c;}
17: }
3
There are three syntax errors. The first is on line 13. The variable a was already used in this scope as a method parameter, so it cannot be reused. The next syntax error comes on line 14 where the code attempts to redeclare local variable b. The third syntax error is quite subtle and on line 16. See it? Look really closely.
The variable p1 is missing a semicolon at the end. There is a semicolon before the }, but that is inside the block. While you don’t normally have to look for missing semicolons, lambdas are tricky in this space,so beware!
is this code legal?
public class Crow { private String color; public void caw(String name) { String volume = "loudly"; Consumer consumer = s -> System.out.println(name + " says " \+ volume + " that she is " + color); }}
Legal.
This shows that lambda can access an instance variable, method parameter, or local variable under certain conditions. Instance variables (and class variables) are always allowed
what lines contain compilation errors?
2: public class Crow {
3: private String color;
4: public void caw(String name) {
5: String volume = “loudly”;
6: name = “Caty”;
7: color = “black”;
8:
9: Consumer consumer = s ->
10: System.out.println(name + “ says “
11: + volume + “ that she is “ + color);
12: volume = “softly”;
13: }
14: }
10, 11
In this example, name is not effectively final because it is set on line 6.However, the compiler error occurs on line 10. It’s not a problem to assign a value to a non final variable. However, once the lambda tries to use it, we do have a problem. The variable is no longer effectively final, so the lambda is not allowed to use the variable.
The variable volume is not effectively final either since it is updated online 12. In this case, the compiler error is on line 11. That’s before the assignment! Again, the act of assigning a value is only a problem from the point of view of the lambda. Therefore, the lambda has to be the-one to generate the compiler error.
what are the rules for accessing a variable from a lambda body inside a method?
Instance variable Static variable Local variable Method variable Lambda variable
Instance variable - Allowed
Static variable - Allowed
Local variable - Allowed if effectively final
Method variable - Allowed if effectively final
Lambda variable - Allowed
what will the list contain after running the code?
3: List < String > bunnies = new ArrayList<>();
4: bunnies.add(“long ear”);
5: bunnies.add(“floppy”);
6: bunnies.add(“hoppy”);
7: System.out.println(bunnies);
8: bunnies.removeIf(s -> s.charAt(0) != ‘h’);
9: System.out.println(bunnies);
[hoppy]
What is the result of the following class?
1: import java.util.function.*; 2: 3: public class Panda { 4: int age; 5: public static void main(String[] args) { 6: Panda p1 = new Panda(); 7: p1.age = 1; 8: check(p1, p -> p.age < 5); 9: } 10: private static void check(Panda panda, 11: Predicate < Panda > pred) { 12: String result = 13: pred.test(panda) ? "match" : "not match"; 14: System.out.print(result); 15: } }
A. match B. not match C. Compiler error on line 8. D. Compiler error on lines 10 and 11. E. Compiler error on lines 12 and 13. F. A runtime exception is thrown.
A. This code is correct. Line 8 creates a lambda expression that checks whether the age is less than 5. Since there is only one parameter and it does not specify a type, the parentheses around the type parameter are optional. Lines 11 and 13 use the Predicateinterface, which declares a test() method.
What is the result of the following code?
1: interface Climb {
2: boolean isTooHigh(int height, int limit);
3: }
4:
5: public class Climber {
6: public static void main(String[] args) {
7: check((h, m) -> h.append(m).isEmpty(), 5);
8: }
9: private static void check(Climb climb, int height) {
10: if (climb.isTooHigh(height, 10))
11: System.out.println(“too high”);
12: else
13: System.out.println(“ok”);
14: }
15: }
A. ok B. too high C. Compiler error on line 7. D. Compiler error on line 10. E. Compiler error on a different line. F. A runtime exception is thrown.
C. The interface takes two int parameters. The code on line 7attempts to use them as if one is a String. It is tricky to use types in a lambda when they are implicitly specified. Remember to check the interface for the real type.
Which of the following lambda expressions can fill in the blank?(Choose all that apply.)
List < String > list = new ArrayList<>();
list.removeIf(___________________);
A. s -> s.isEmpty() B. s -> {s.isEmpty()} C. s -> {s.isEmpty();} D. s -> {return s.isEmpty();} E. String s -> s.isEmpty() F. (String s) -> s.isEmpty()
A, D, F. The removeIf() method expects a Predicate, which takes a parameter list of one parameter using the specified type. Options B and C are incorrect because they do not use the return keyword.This keyword is required to be inside the braces of a lambda body.Option E is incorrect because it is missing the parentheses around the parameter list. This is only optional for a single parameter with an inferred type.
Which lambda can replace the MySecret class to return the samevalue? (Choose all that apply.)
interface Secret { String magic(double d); }
class MySecret implements Secret { public String magic(double d) {return "Poof"; }}
A. (e) -> “Poof”
B. (e) -> {“Poof”}
C. (e) -> { String e = “”; “Poof” }
D. (e) -> { String e = “”; return “Poof”; }
E. (e) -> { String e = “”; return “Poof” }
F. (e) -> { String f = “”; return “Poof”; }
A, F. Option B is incorrect because it does not use the return keyword. Options C, D, and E are incorrect because the variable e is already in use from the lambda and cannot be redefined. Additionally, option C is missing the return keyword, and option E is missing the semicolon
Which of the following lambda expressions can be passed to a function of Predicate < String > type? (Choose all that apply.)
A. () -> s.isEmpty() B. s -> s.isEmpty() C. String s -> s.isEmpty() D. (String s) -> s.isEmpty() E. (s1) -> s.isEmpty() F. (s1, s2) -> s1.isEmpty()
B, D. Predicate takes a parameter list of one parameter using the specified type. Options A and F are incorrect because they specify the wrong number of parameters. Option C is incorrect because parentheses are required around the parameter list when the type is specified. Option E is incorrect because the name used in the parameter list does not match the name used in the body.
Which of these statements is true about the following code?
public void method() {
x((var x) -> {}, (var x, var y) -> 0);
}
public void x(Consumer < String > x, Comparator < Boolean > y)
{
}
A. The code does not compile because of one of the variables named x.
B. The code does not compile because of one of the variables named y.
C. The code does not compile for another reason.
D. The code compiles, and the var in each lambda refers to the same type.
E. The code compiles, and the var in each lambda refers to a different type.
E. While there appears to have been a variable name shortage when this code was written, it does compile. Lambda variables and method names are allowed to be the same. The x lambda parameter is scoped to within each lambda, so it is allowed to be reused. The type is inferred by the method it calls. The first lambda maps x to a String and the second to a Boolean. Therefore,option E is correct.