Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Learn-Java-with-Projects.iml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_21_PREVIEW" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
Expand Down
157 changes: 44 additions & 113 deletions ch14/MethodReferenceTypes.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package lets_get_certified.lambdas;
package ch14;

import java.util.ArrayList;
import java.util.Arrays;
Expand All @@ -11,139 +11,70 @@
import java.util.function.Supplier;

public class MethodReferenceTypes {
public static void main(String[] args) {
// boundMethodReferences(); // bound
// unboundMethodReferences(); // unbound
public static void main(String[] args) {
boundMethodReferences(); // bound
unboundMethodReferences(); // unbound
constructorMethodReferences(); // constructor
// staticMethodReferences(); // static
staticMethodReferences(); // static
}

public static void boundMethodReferences(){
String name = "Mr. Joe Bloggs";
// Supplier<T>
// T get()
Supplier<String> lowerL = () -> name.toLowerCase(); // lambda
Supplier<String> lowerMR = name::toLowerCase; // method reference

// No need to say which instance to call it on - the supplier is bound to name
System.out.println(lowerL.get()); // mr. joe bloggs
System.out.println(lowerMR.get());// mr. joe bloggs


// Supplier<T>
// T get()
Supplier<String> lowerMR = name::toLowerCase; // method reference
System.out.println(lowerMR.get()); // mr. Joe Bloggs

// Predicate<T>
// boolean test(T t)
// Even though startsWith is overloaded, boolean startsWith(String) and
// boolean startsWith(String, int), because we are creating a Predicate which
// has a functional method of test(T t), the startsWith(String) is used.
// This is where "context" is important.
Predicate<String> titleL = (title) -> name.startsWith(title);
// boolean test(T t)
Predicate<String> titleMR = name::startsWith;

System.out.println(titleL.test("Mr.")); // true
System.out.println(titleMR.test("Ms."));// false
System.out.println(titleMR.test("Mr.")); // true
System.out.println(titleMR.test("Ms.")); // false
}

public static void unboundMethodReferences(){
// Function<T, R>
// R apply(T)
// String apply(String)
Function<String, String> upperL = s -> s.toUpperCase();
Function<String, String> upperMR = String::toUpperCase;
// The function is unbound, so you need to specify which instance to call it on
System.out.println(upperL.apply("sean")); // SEAN
System.out.println(upperMR.apply("sean")); // SEAN

// Function<T, U, R>
// R apply(T t, U u)
// String apply(String, String)
BiFunction<String, String, String> concatL = (s1, s2) -> s1.concat(s2);
BiFunction<String, String, String> concatMR = String::concat;
System.out.println(concatL.apply("Sean ", "Kennedy"));// Sean Kennedy

// 1st parameter is used for executing the instance method
// "Sean ".concat("Kennedy")
System.out.println(concatMR.apply("Sean ", "Kennedy"));// Sean Kennedy
// Function<T, R>
// R apply(T t)
Function<String, String> upperMR = String::toUpperCase;
System.out.println(upperMR.apply("sean")); // SEAN

// BiFunction<T, U, R>
// R apply(T t, U u)
BiFunction<String, String, String> concatMR = String::concat;
System.out.println(concatMR.apply("Sean ", "Kennedy")); // Sean Kennedy
}








public static void constructorMethodReferences(){
// Supplier<T>
// T get()
Supplier<StringBuilder> sbL = () -> new StringBuilder(); // lambda
Supplier<StringBuilder> sbMR = StringBuilder::new; // method reference
StringBuilder sb1 = sbL.get(); sb1.append("lambda version"); System.out.println(sb1);
StringBuilder sb2 = sbMR.get(); sb2.append("method reference version"); System.out.println(sb2);

// Function<T, R>
// R apply(T)
// List<String> apply(Integer)
// ArrayList(int initialCapacity)
Function<Integer, List<String>> alL = x -> new ArrayList(x);
Function<Integer, List<String>> alMR = ArrayList::new;
List<String> ls1 = alL.apply(100); // initial capacity 100
ls1.add("21");
System.out.println(ls1);//[21]
List<String> ls2 = alMR.apply(200); // initial capacity 200
ls2.add("88");
System.out.println(ls2);//[88]
// Supplier<T>
// T get()
Supplier<StringBuilder> sbMR = StringBuilder::new; // method reference
StringBuilder sb = sbMR.get();
sb.append("method reference version");
System.out.println(sb);

// Function<T, R>
// R apply(T t)
Function<Integer, List<String>> alMR = ArrayList::new;
List<String> ls = alMR.apply(200); // initial capacity 200
ls.add("88");
System.out.println(ls); // [88]
}











public static void staticMethodReferences(){
// Static method references are considered UNBOUND also. An example static method
// is Collections.sort(List)
// Consumer<T>
// void accept(T t)
// void accept(List<Integer>)
// NB: Consumer takes one parameter => sort(List) is used, as opposed to sort(List, Comparator)
Consumer<List<Integer>> sortL = list -> Collections.sort(list);
// Consumer<T>
// void accept(T t)
Consumer<List<Integer>> sortMR = Collections::sort;

List<Integer> listOfNumbers = Arrays.asList(2,1,5,4,9);
sortL.accept(listOfNumbers);// execution
System.out.println(listOfNumbers); // [1, 2, 4, 5, 9]

listOfNumbers = Arrays.asList(8,12,4,3,7);
sortMR.accept(listOfNumbers);// execution
System.out.println(listOfNumbers); // [3, 4, 7, 8, 12]
List<Integer> listOfNumbers = Arrays.asList(8, 12, 4, 3, 7);
sortMR.accept(listOfNumbers); // execution
System.out.println(listOfNumbers); // [3, 4, 7, 8, 12]
}


}















class X implements Consumer{

@Override
public void accept(Object arg0) {
System.out.println("----"+arg0);
}

}
/*
X x = new X();
x.accept("abc");
Expand Down
133 changes: 48 additions & 85 deletions ch16/Optionals.java
Original file line number Diff line number Diff line change
@@ -1,117 +1,80 @@
package ch16;

import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.stream.IntStream;

public class Optionals {

public static void main(String[] args) {
// doOptionalPrimitiveAverage();
doOptionalPrimitiveAverage();
doOptionalAPI();
// createOptionals();
// doOptionalNull();
createOptionals();
doOptionalNull();
}
public static void createOptionals(){
Optional opt1 = Optional.empty();
// System.out.println(opt1.get()); // NoSuchElementException
opt1.ifPresent(o -> System.out.println("opt1: "+o)); // no exception

Optional opt2 = Optional.of(23);
// Optional.of(null); // NullPointerException
opt2.ifPresent(o -> System.out.println("opt2: "+o)); // opt2: 23
public static void createOptionals() {
Optional<Object> opt1 = Optional.empty();
opt1.ifPresent(System.out::println);

Optional<Integer> opt2 = Optional.of(23);
opt2.ifPresent(System.out::println);

Optional opt3 = Optional.ofNullable(23);
opt3.ifPresent(o -> System.out.println("opt3: "+o)); // opt3: 23
Optional<Integer> opt3 = Optional.of(23);
opt3.ifPresent(System.out::println);

Optional opt4 = Optional.ofNullable(null);
opt4.ifPresent(o -> System.out.println("opt4: "+o));
if(opt4.isEmpty()){
System.out.println("opt4 is empty!"); // opt4 is empty!
Optional<Object> opt4 = Optional.empty();
opt4.ifPresent(System.out::println);
if (opt4.isEmpty()) {
System.out.println("opt4 is empty!"); // opt4 is empty!
}
}
public static void doOptionalPrimitiveAverage(){

public static void doOptionalPrimitiveAverage() {
OptionalDouble optAvg = IntStream.rangeClosed(1, 10).average();
optAvg.ifPresent(d -> System.out.println(d));// 5.5
System.out.println(optAvg.getAsDouble());// 5.5
double dblAvg = optAvg.orElseGet(() -> Double.NaN);
System.out.println(dblAvg);// 5.5
optAvg.ifPresent(System.out::println); // 5.5
if (optAvg.isPresent()) {
System.out.println(optAvg.getAsDouble()); // 5.5
}
double dblAvg = optAvg.orElse(Double.NaN); // Directly use orElse
System.out.println(dblAvg); // 5.5

OptionalInt optInt = OptionalInt.of(35);
int age = optInt.orElseGet(() -> 0);
System.out.println(age);// 35
System.out.println(optInt.getAsInt());// 35


int age = optInt.orElse(0);
System.out.println(age); // 35
System.out.println(optInt.getAsInt()); // 35
}
public static void doOptionalNull(){

public static void doOptionalNull() {
Optional<String> optSK = howToDealWithNull("SK");
optSK.ifPresent(System.out::println);// SK
optSK.ifPresent(System.out::println); // SK

Optional<String> emptyOpt = howToDealWithNull(null);
System.out.println(
emptyOpt.orElseGet(
() -> "Empty optional"));// Empty optional
}
public static Optional<String> howToDealWithNull(String param){
// return param == null ? Optional.empty() : Optional.of(param);
return Optional.ofNullable(param); // same as line above
System.out.println(emptyOpt.orElseGet(Optionals::getEmptyOptionalMessage)); // Empty optional
}

public static void doOptionalAPI(){
Optional<Double> valueInOptional = Optional.ofNullable(60.0);
if(valueInOptional.isPresent()){
System.out.println(valueInOptional.get()); // 60.0
}
valueInOptional.ifPresent(System.out::println);// 60.0
System.out.println(valueInOptional.orElse(Double.NaN)); // 60.0

Optional<Double> emptyOptional = Optional.ofNullable(null);
System.out.println(emptyOptional.orElse(Double.NaN)); // NaN
System.out.println(emptyOptional.orElseGet(() -> Math.random())); // 0.8524556508038182
System.out.println(emptyOptional.orElseThrow()); // NoSuchElementException
// System.out.println(emptyOptional.orElseThrow(() ->
// new RuntimeException())); // RuntimeException
public static Optional<String> howToDealWithNull(String param) {
return Optional.ofNullable(param);
}

}
/*
save
public static void doOptionalPrimitiveAverage(){
OptionalDouble optAvg = IntStream.rangeClosed(1, 10)
.average();
// DoubleConsumer - functional interface; functional method is:
// void accept(double value)
optAvg.ifPresent((d) -> System.out.println(d));// 5.5
System.out.println(optAvg.getAsDouble());// 5.5
// DoubleSupplier - functional interface; functional method is:
// double getAsDouble()
System.out.println(optAvg.orElseGet(() -> Double.NaN));// 5.5
}

// a long way to calculate average (just for showing Optional)
public static Optional<Double> calcAverage(int... grades){
if(grades.length == 0) return Optional.empty();
int total=0;
for(int grade:grades) total += grade;
return Optional.of((double)total / grades.length);
}
public static void doOptionalAverage(){
Optional<Double> valueInOptional = calcAverage(50, 60, 70);
if(valueInOptional.isPresent()){
System.out.println(valueInOptional.get()); // 60.0
}
valueInOptional.ifPresent(System.out::println);// 60.0
public static void doOptionalAPI() {
Optional<Double> valueInOptional = Optional.of(60.0);
valueInOptional.ifPresent(System.out::println); // 60.0
System.out.println(valueInOptional.orElse(Double.NaN)); // 60.0

Optional<Double> emptyOptional = calcAverage();// will return an empty Optional
Optional<Double> emptyOptional = Optional.empty();
System.out.println(emptyOptional.orElse(Double.NaN)); // NaN
System.out.println(emptyOptional.orElseGet(() -> Math.random())); // 0.8524556508038182
// System.out.println(emptyOptional.orElseThrow()); // NoSuchElementException
System.out.println(emptyOptional.orElseThrow(() -> new RuntimeException())); // RuntimeException
System.out.println(emptyOptional.orElseGet(Math::random)); // Random number
try {
System.out.println(emptyOptional.orElseThrow(NoSuchElementException::new)); // NoSuchElementException
} catch (NoSuchElementException e) {
System.out.println("Exception caught: " + e);
}
}

*/
private static String getEmptyOptionalMessage() {
return "Empty optional";
}
}
Loading