JAVA 8 LAMBDA Expressions AND Stream API - EXAMPLES
Examples :
Simple sintax:
a -> a.canHop()
(Animal a) -> { return a.canHop(); } // blok iceriinde yazilanda return ve noqeteli vergul de olmalidi
(a, b) -> { int a = 0; return 5;} // DOES NOT COMPILE
// Cunki declare olunmus deyiskeni yeniden tanimlamaga qoymur
A boolean expression : (List<String> list) -> list.isEmpty()
Creating objects : () -> new Apple(10)
Consuming from an object : (Apple a) -> { System.out.println(a.getWeight()); }
Select/extract from an object : (String s) -> s.length()
Combine two values : (int a, int b) -> a * b
Compare two objects : (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight())
List<Apple> greenApples = filter(inventory, (Apple a) -> "green".equals(a.getColor()));
//In the code shown here, you can pass a lambda as second argument to the
method filter because it expects a Predicate<T>,
Predicate istifadesi:
En sade formada istifadesi:
Predicate<Integer> pr = a -> (a > 18); // Creating predicate
System.out.println(pr.test(10)); // Calling Predicate method
System.out.println(pr.test(10)); // Calling Predicate method
Output : false
- public class PredicateInterfaceExample {
- static Boolean checkAge(int age){
- if(age>17)
- return true;
- else return false;
- }
- public static void main(String[] args){
- // Using Predicate interface
- Predicate<Integer> predicate = PredicateInterfaceExample::checkAge;
- // Calling Predicate method
- boolean result = predicate.test(25);
- System.out.println(result);
- }
- }
@FunctionalInterface
public interface Predicate<T>{
boolean test(T t);
}
public static <T> List<T> filter(List<T> list, Predicate<T> p) {
List<T> results = new ArrayList<>();
for(T s: list){
if(p.test(s)){
results.add(s);
}
}
return results;
}
Predicate<String> nonEmptyStringPredicate = (String s) -> ! s.isEmpty();
List<String> nonEmpty = filter(listOfStrings, nonEmptyStringPredicate);
public class Main {
public static void main(String[] argv) {
engine((x,y)-> x + y);
engine((x,y)-> x * y);
engine((x,y)-> x / y);
engine((x,y)-> x % y);
}
private static void engine(Calculator calculator){
int x = 2, y = 4;
int result = calculator.calculate(x,y);
System.out.println(result);
}
}
@FunctionalInterface
interface Calculator{
int calculate(int x, int y);
}
public static void main(String[] argv) {
engine((x,y)-> x + y);
engine((x,y)-> x * y);
engine((x,y)-> x / y);
engine((x,y)-> x % y);
}
private static void engine(Calculator calculator){
int x = 2, y = 4;
int result = calculator.calculate(x,y);
System.out.println(result);
}
}
@FunctionalInterface
interface Calculator{
int calculate(int x, int y);
}
public class Main {
public static void main(String[] argv) {
engine((int x,int y)-> x + y);
engine((long x, long y)-> x * y);
engine((int x,int y)-> x / y);
engine((long x,long y)-> x % y);
}
private static void engine(IntCalculator calculator){
int x = 2, y = 4;
int result = calculator.calculate(x,y);
System.out.println(result);
}
private static void engine(LongCalculator calculator){
long x = 2, y = 4;
long result = calculator.calculate(x,y);
System.out.println(result);
}
}
@FunctionalInterface
interface IntCalculator{
int calculate(int x, int y);
}
@FunctionalInterface
interface LongCalculator{
long calculate(long x, long y);
}
public static void main(String[] argv) {
engine((int x,int y)-> x + y);
engine((long x, long y)-> x * y);
engine((int x,int y)-> x / y);
engine((long x,long y)-> x % y);
}
private static void engine(IntCalculator calculator){
int x = 2, y = 4;
int result = calculator.calculate(x,y);
System.out.println(result);
}
private static void engine(LongCalculator calculator){
long x = 2, y = 4;
long result = calculator.calculate(x,y);
System.out.println(result);
}
}
@FunctionalInterface
interface IntCalculator{
int calculate(int x, int y);
}
@FunctionalInterface
interface LongCalculator{
long calculate(long x, long y);
}
Output :
true
false
false
Predicate Interface
Predicate interface is defined in java.util.function package :
Output :
John
Jane
Jane
Output :
Count of negative numbers in list numbers = 3
Predicate chaining using and(), or() methods
We can use and() and or() methods to chain predicates as shown in following examples :
Output :
Multiples of 2 and 3 in numbers list are :
18
24
18
24
Output :
Multiples of 2 or 3 in numbers list are :
10
18
21
24
10
18
21
24
Predicate advantages
Predicates can help avoid duplicate lambda expression as shown in below code :
Output :
Count of negative numbers in list numbers = 3
Count of negative numbers in list moreNumbers = 6
Count of negative numbers in list moreNumbers = 6
Lambda expressions can be used only in the following four contexts.
- Assignment Context
- Method Invocation Context
- Return Context
- Cast Context
Assignment Context
A lambda expression can appear to the right of the assignment operator.
public class Main {
public static void main(String[] argv) {
Calculator iCal = (x,y)-> x + y;
System.out.println(iCal.calculate(1, 2));
}
}
@FunctionalInterface
interface Calculator{
int calculate(int x, int y);
}
public static void main(String[] argv) {
Calculator iCal = (x,y)-> x + y;
System.out.println(iCal.calculate(1, 2));
}
}
@FunctionalInterface
interface Calculator{
int calculate(int x, int y);
}
The code above generates the following result.
Method Invocation Context
We can use a lambda expression as an argument for a method or constructor.
public class Main {
public static void main(String[] argv) {
engine((x,y)-> x / y);
}
private static void engine(Calculator calculator){
long x = 2, y = 4;
long result = calculator.calculate(x,y);
System.out.println(result);
}
}
@FunctionalInterface
interface Calculator{
long calculate(long x, long y);
}
public static void main(String[] argv) {
engine((x,y)-> x / y);
}
private static void engine(Calculator calculator){
long x = 2, y = 4;
long result = calculator.calculate(x,y);
System.out.println(result);
}
}
@FunctionalInterface
interface Calculator{
long calculate(long x, long y);
}
The code above generates the following result.
Return Context
We can use a lambda expression in a return statement, and its target type is declared in the method return type.
public class Main {
public static void main(String[] argv) {
System.out.println(create().calculate(2, 2));
}
private static Calculator create(){
return (x,y)-> x / y;
}
}
@FunctionalInterface
interface Calculator{
long calculate(long x, long y);
}
public static void main(String[] argv) {
System.out.println(create().calculate(2, 2));
}
private static Calculator create(){
return (x,y)-> x / y;
}
}
@FunctionalInterface
interface Calculator{
long calculate(long x, long y);
}
The code above generates the following result.
Cast Context
We can use a lambda expression preceded by a cast. The type specified in the cast is its target type.
public class Main {
public static void main(String[] argv) {
engine((IntCalculator) ((x,y)-> x + y));
}
private static void engine(IntCalculator calculator){
int x = 2, y = 4;
int result = calculator.calculate(x,y);
System.out.println(result);
}
private static void engine(LongCalculator calculator){
long x = 2, y = 4;
long result = calculator.calculate(x,y);
System.out.println(result);
}
}
@FunctionalInterface
interface IntCalculator{
int calculate(int x, int y);
}
@FunctionalInterface
interface LongCalculator{
long calculate(long x, long y);
}
public static void main(String[] argv) {
engine((IntCalculator) ((x,y)-> x + y));
}
private static void engine(IntCalculator calculator){
int x = 2, y = 4;
int result = calculator.calculate(x,y);
System.out.println(result);
}
private static void engine(LongCalculator calculator){
long x = 2, y = 4;
long result = calculator.calculate(x,y);
System.out.println(result);
}
}
@FunctionalInterface
interface IntCalculator{
int calculate(int x, int y);
}
@FunctionalInterface
interface LongCalculator{
long calculate(long x, long y);
}
The code above generates the following result.
FUNCTIONAL INTREFACE
The following is an example of such a functional interface:
@FunctionalInterface
interface Processor {
int getStringLength(String str);
}
interface Processor {
int getStringLength(String str);
}
We can assign lambda expression to its functional interface instance.
Processor stringProcessor = (String str) -> str.length();
Generic Functional Interface
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
}
public interface Comparator<T> {
int compare(T o1, T o2);
}
@FunctionalInterface
public interface Processor {
<T> void process(T[] list);
}
public interface Processor {
<T> void process(T[] list);
}
CONSUMER istifadesi
Consumer<String> consumerStr=s->{
System.out.println(s);
};
consumerStr.accept("Hello Java.");
consumerStr.accept("Hello World.");
Consumer<Integer> consumerInt=i->{
System.out.println("Integer value="+i);
};
consumerInt.accept(5);
consumerInt.accept(8);
System.out.println(s);
};
consumerStr.accept("Hello Java.");
consumerStr.accept("Hello World.");
Consumer<Integer> consumerInt=i->{
System.out.println("Integer value="+i);
};
consumerInt.accept(5);
consumerInt.accept(8);
The expression System.out::println is a method reference that is equivalent to the
lambda expression x -> System.out.println(x).
button.setOnAction(event -> System.out.println(event));
Is same with
button.setOnAction(System.out::println);
Similarly, Math::pow is
equivalent to (x, y) -> Math.pow(x, y).
this::equals is the same as x -> this.equals(x).
Super classin metodunu cagirmaq :: ile :
class Greeter {
public void greet() {
System.out.println("Hello, world!");
}
}
class ConcurrentGreeter extends Greeter {
public void greet() {
Thread t = new Thread(super::greet);
t.start();
}
}
Foreach:
persons.forEach(p -> p.setLastName("Doe"));
for (int i = 0; i < list.size(); i++)
System.out.println(list.get(i));
Is same with
list.forEach(System.out::println);
public static void main(String[] args) {
//simple object list
List<Animal> animalList= new ArrayList<Animal>();
animalList.add(new Animal("cat",true));
animalList.add(new Animal("kangroo",true));
animalList.add(new Animal("ant",false));
animalList.add(new Animal("fish",false));
//foreach system out list object propeties
animalList.forEach(animal->{
System.out.print(animal.getName());
System.out.println("isCanHop="+animal.isCanHop());
});
}
//Listin itertor vasitesile loopu
Iterator<Animal> it = animalList.iterator();
while(it.hasNext()){
Animal a = it.next();
System.out.println("Iterator Value::"+a.getName());
}
//Anonimus class yaradaraq listin loopu
animalList.forEach(new Consumer<Animal>() {
public void accept(Animal a) {
System.out.println("forEach anonymous class Value::"+a.getName());
}
});
//Consumer functional interfesinden istfde ederek listin loopu
MyConsumer action = new MyConsumer();
animalList.forEach(action);
class MyConsumer implements Consumer<Animal>{
public void accept(Animal a) {
System.out.println("Consumer impl Value::"+a.getName());
}
}
BiFunction istifadesi
class Arithmetic{
public static int add(int a, int b){
return a+b;
}
public static float add(int a, float b){
return a+b;
}
public static float add(float a, float b){
return a+b;
}
}
BiFunction<Integer, Integer, Integer>adder1 = Arithmetic::add;
BiFunction<Integer, Float, Float>adder2 = Arithmetic::add;
BiFunction<Float, Float, Float>adder3 = Arithmetic::add;
int result1 = adder1.apply(10, 20);
float result2 = adder2.apply(10, 20.0f);
float result3 = adder3.apply(10.0f, 20.0f);
System.out.println(result1);
System.out.println(result2);
System.out.println(result3);
(Stream filter) count all long words in a book:
you can turn any collection into a stream with the
stream method that Java 8 added to the Collection interface.
String contents = new String(Files.readAllBytes(
Paths.get("alice.txt")), StandardCharsets.UTF_8); // Read file into string
List<String> words = Arrays.asList(contents.split("[\\P{L}]+"));
//Now we are ready to iterate:
int count = 0;
for (String w : words) {
if (w.length() > 12) count++;
}
Is same with
long count = words.stream().filter(w -> w.length() > 12).count();
paralelStream:
long count = words.parallelStream().filter(w -> w.length() > 12).count();
Array to stream :
Stream<String> words = Stream.of(contents.split("[\\P{L}]+"));
// split returns a String[] array
The of method has a varargs parameter, so you can construct a stream from any
number of arguments:
Stream<String> song = Stream.of("gently", "down", "the", "stream");
Use Arrays.stream(array, from, to) to make stream from a part of an array.
To make a stream with no elements, use the static Stream.empty method:
Stream<String> silence = Stream.empty();
// Generic type <String> is inferred; same as Stream.<String>empty()
The Stream interface has two static methods for making infinite streams. The
generate method takes a function with no arguments :
Stream<String> echos = Stream.generate(() -> "Echo");
To produce infinite sequences such as 0 1 2 3 …
Stream<Double> randoms = Stream.generate(Math::random);
FİLTER
Filter : person which age > 18
Stream<Person> personsOver18 = persons.stream().filter(p -> p.getAge() > 18);
Filter : person whose names stars with “p”
List<Person> filtered =
persons
.stream()
.filter(p -> p.name.startsWith("P"))
.collect(Collectors.toList());
System.out.println(filtered);
persons
.stream()
.filter(p -> p.name.startsWith("P"))
.collect(Collectors.toList());
System.out.println(filtered);
*** collect ile streami liste yiga bilirik
Double Filter :
// Using multiple filter
System.out.println("Element whose length is > 5 and startswith G");
versions.stream() .filter(s -> s.length() > 8) .filter(s -> s.startsWith("G")) .forEach(System.out::println);
Filter : author of book equal someone
filter(books, b -> "Lewis Carrol".equals(b.getAuthor()));
Filter : people whose name is Jon
peoples.stream().filter( p -> p.firstName.equals(”Jon”)).collect(Collectors.toList())
*** stream() metodundan listi stream-e cevirmek ucun istifade edilir
Using map, filtermap :
you can transform all words to lowercase like this:
Stream<String> lowercaseWords = words.map(String::toLowerCase);
When you use map, a function is applied to each element, and the return values
are collected in a new stream.
Now suppose that you have a function that returns
not just one value but a stream of values, such as this one:
public static Stream<Character> characterStream(String s) {
List<Character> result = new ArrayList<>();
for (char c : s.toCharArray()) result.add(c);
return result.stream();
}
For example, characterStream("boat") is the stream ['b', 'o', 'a', 't']. Suppose you
map this method on a stream of strings:
Stream<Stream<Character>> result = words.map(w -> characterStream(w));
You will get a stream of streams, like [... ['y', 'o', 'u', 'r'], ['b', 'o', 'a', 't'],
...] To flatten it out to a stream of characters [... 'y', 'o', 'u', 'r', 'b', 'o', 'a',
't', ...], use the flatMap method instead of map:
Stream<Character> letters = words.flatMap(w -> characterStream(w))
// Calls characterStream on each word and flattens the results
ArrayList to map:
Map<String, Integer> map8 = listOfString.stream().collect(toMap(s -> s , s -> s.length()));
Extracting Substreams and Combining Streams:
The call stream.limit(n) returns a new stream that ends after n elements (or when
the original stream ends if it is shorter).
Stream<Double> randoms = Stream.generate(Math::random).limit(100);
yields a stream with 100 random numbers.
The call stream.skip(n) does the exact opposite. It discards the first n elements.
Stream<String> words = Stream.of(contents.split("[\\P{L}]+")).skip(1);
You can concatenate two streams with the static concat method of the Stream class
Stream<Character> combined = Stream.concat(
characterStream("Hello"), characterStream("World"));
// Yields the stream ['H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd']
:
Group by : group by person age
Map<Integer, List<Person>> personsByAge = persons
.stream()
.collect(Collectors.groupingBy(p -> p.age));
personsByAge
.forEach((age, p) -> System.out.format("age %s: %s\n", age, p));
.stream()
.collect(Collectors.groupingBy(p -> p.age));
personsByAge
.forEach((age, p) -> System.out.format("age %s: %s\n", age, p));
Sorting : sort person list
Collections.sort(personList, (Person p1, Person p2) -> p1.firstName.compareTo(p2.firstName));
Filter , sort and collect
List lowCaloricDishesName =
dishes.stream()
.filter(d->d.getCalories()<400)
.sorted(comparing(Dish::getCalories))
.map(Dish::getName)
.collect(toList());
Convert Stream to List :
Stream<Integer> number = Stream.of(1, 2, 3, 4, 5);
List<Integer> result2 = number.filter(x -> x!= 3).collect(Collectors.toList());
Convert Map to List :
Map<Integer, String> map = new HashMap<>();
map.put(10, "apple");
map.put(20, "orange");
map.put(30, "banana");
map.put(40, "watermelon");
map.put(50, "dragonfruit");
System.out.println("\n1. Export Map Key to List...");
List<Integer> result = map.keySet().stream()
.collect(Collectors.toList());
map.put(10, "apple");
map.put(20, "orange");
map.put(30, "banana");
map.put(40, "watermelon");
map.put(50, "dragonfruit");
System.out.println("\n1. Export Map Key to List...");
List<Integer> result = map.keySet().stream()
.collect(Collectors.toList());
Convert List to Map :
List<Hosting> list = new ArrayList<>();
list.add(new Hosting(1, "liquidweb.com", 80000));
list.add(new Hosting(2, "linode.com", 90000));
list.add(new Hosting(3, "digitalocean.com", 120000));
list.add(new Hosting(4, "aws.amazon.com", 200000));
list.add(new Hosting(5, "mkyong.com", 1));
list.add(new Hosting(6, "linode.com", 100000));
Map result1 = list.stream()
.sorted(Comparator.comparingLong(Hosting::getWebsites).reversed())
.collect(
Collectors.toMap(
Hosting::getName, Hosting::getWebsites, // key = name, value websites
(oldValue, newValue) -> oldValue, // if same key, take the old key
LinkedHashMap::new // returns a LinkedHashMap, keep order
));
System.out.println("Result 1 : " + result1);
list.add(new Hosting(1, "liquidweb.com", 80000));
list.add(new Hosting(2, "linode.com", 90000));
list.add(new Hosting(3, "digitalocean.com", 120000));
list.add(new Hosting(4, "aws.amazon.com", 200000));
list.add(new Hosting(5, "mkyong.com", 1));
list.add(new Hosting(6, "linode.com", 100000));
Map result1 = list.stream()
.sorted(Comparator.comparingLong(Hosting::getWebsites).reversed())
.collect(
Collectors.toMap(
Hosting::getName, Hosting::getWebsites, // key = name, value websites
(oldValue, newValue) -> oldValue, // if same key, take the old key
LinkedHashMap::new // returns a LinkedHashMap, keep order
));
System.out.println("Result 1 : " + result1);
Read file line by line :
String fileName = "c://lines.txt";
//read file into stream, try-with-resources
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
stream.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
//read file into stream, try-with-resources
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
stream.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
String to char array :
String password = "password123";
password.chars() //IntStream
.mapToObj(x -> (char) x)//Stream<Character>
.forEach(System.out::println);
password.chars() //IntStream
.mapToObj(x -> (char) x)//Stream<Character>
.forEach(System.out::println);
Group by a List and display the total count of it :
List<String> items =
Arrays.asList("apple", "apple", "banana",
"apple", "orange", "banana", "papaya");
Map<String, Long> result =
items.stream().collect(
Collectors.groupingBy(
Function.identity(), Collectors.counting()
)
);
System.out.println(result);
Arrays.asList("apple", "apple", "banana",
"apple", "orange", "banana", "papaya");
Map<String, Long> result =
items.stream().collect(
Collectors.groupingBy(
Function.identity(), Collectors.counting()
)
);
System.out.println(result);
output
{
papaya=1, orange=1, banana=2, apple=3
}
papaya=1, orange=1, banana=2, apple=3
}
Groub by object List :
//3 apple, 2 banana, others 1
List<Item> items = Arrays.asList(
new Item("apple", 10, new BigDecimal("9.99")),
new Item("banana", 20, new BigDecimal("19.99")),
new Item("orang", 10, new BigDecimal("29.99")),
new Item("watermelon", 10, new BigDecimal("29.99")),
new Item("papaya", 20, new BigDecimal("9.99")),
new Item("apple", 10, new BigDecimal("9.99")),
new Item("banana", 10, new BigDecimal("19.99")),
new Item("apple", 20, new BigDecimal("9.99"))
);
Map<String, Long> counting = items.stream().collect(
Collectors.groupingBy(Item::getName, Collectors.counting()));
System.out.println(counting);
Map<String, Integer> sum = items.stream().collect(
Collectors.groupingBy(Item::getName, Collectors.summingInt(Item::getQty)));
System.out.println(sum);
List<Item> items = Arrays.asList(
new Item("apple", 10, new BigDecimal("9.99")),
new Item("banana", 20, new BigDecimal("19.99")),
new Item("orang", 10, new BigDecimal("29.99")),
new Item("watermelon", 10, new BigDecimal("29.99")),
new Item("papaya", 20, new BigDecimal("9.99")),
new Item("apple", 10, new BigDecimal("9.99")),
new Item("banana", 10, new BigDecimal("19.99")),
new Item("apple", 20, new BigDecimal("9.99"))
);
Map<String, Long> counting = items.stream().collect(
Collectors.groupingBy(Item::getName, Collectors.counting()));
System.out.println(counting);
Map<String, Integer> sum = items.stream().collect(
Collectors.groupingBy(Item::getName, Collectors.summingInt(Item::getQty)));
System.out.println(sum);
File ile islemek :
File dir = new File("/images");
String[] imglist = dir.list((f, s) -> { return s.endsWith(".jpg"); });
String[] imglist = dir.list((f, s) -> { return s.endsWith(".jpg"); });
Counting London-based artists using internal iteration
EXAMPLE:
int count = 0;
Iterator<Artist> iterator = allArtists.iterator();
while(iterator.hasNext()) {
Artist artist = iterator.next();
if (artist.isFrom("London")) {
count++;
}
}
long count = allArtists.stream()
.filter(artist -> artist.isFrom("London"))
.count();
Example 3-5. Not printing out artist names due to lazy evaluation
allArtists.stream()
.filter(artist -> {
System.out.println(artist.getName());
return artist.isFrom("London");
});
Yorumlar
Yorum Gönder