Java8

Die größte Neuerung auf der Sprachseite von Java 8 sind Lambda-Ausdrücke. In Java 8 können in Interfaces auch nicht-abstrakte Methoden haben. Weiter wurden das funktionale Interface eingeführt.

Methoden in Interfaces, class ABImpl


package de.snowbits.j8;

public class ABImpl implements A, B {

	@Override
	public void doSomething() {
		System.out.println("ABImpl");
		A.super.doSomething(); // A.super syntax
		B.super.doSomething(); // B.super syntax
	}
	
	public static void main(String[] args) {
		ABImpl testImpl = new ABImpl();
		testImpl.doSomething(); 
		
		// ABCImpl 
		// A 
		// B
	}

}
	

Interface A


package de.snowbits.j8;

public interface A {
	
	default void doSomething() {
		System.out.println("A");
	}
	
}
	

Interface B


package de.snowbits.j8;

public interface B {
	
	default void doSomething() {
		System.out.println("B");
	}
	
}
	

class Java8Examples


package de.snowbits.j8;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.OptionalDouble;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import de.snowbits.j8.Person.Sex;

public class Java8Examples {

	public static Function<Integer, Integer> square = (x) -> x * x;
	public static BiFunction<Integer, Integer, Integer> squareAdd = (x, y) -> x * x + y * y;

	public static void main(String[] args) {
		int testStep = 1;
		debugNextStageWithLineSeperator(testStep++);

		System.out.println(square.apply(5));
		System.out.println(squareAdd.apply(5, 10));
		// 25
		// 125

		debugNextStageWithLineSeperator(testStep++);
		
		int c = 3; // wird zur Konstante und ist nicht mehr änderbar.
		Function<Double, Double> function = a -> a * a / c; 
		System.out.println(function.apply(9d));	
		// 27.0

		debugNextStageWithLineSeperator(testStep++);
		
		Function<String, Function<String,String>> factory = name -> (sort -> name + " \t= " + sort);
		Function<String, String> fruit = factory.apply( "Obst");
		Function<String, String> vegetable = factory.apply( "Gemüse");
		System.out.println(fruit.apply("Apfel"));	
		System.out.println(fruit.apply("Birne"));	
		System.out.println(vegetable.apply( "Gurke"));	
		System.out.println(vegetable.apply( "Kohl"));
		// Obst 	= Apfel
		// Obst 	= Birne
		// Gemüse 	= Gurke
		// Gemüse 	= Kohl		

		debugNextStageWithLineSeperator(testStep++);
		
		List<Person> persons = Arrays.asList(new Person[] { 
				new Person(Sex.MALE, "Max", "Muster", 25),
				new Person(Sex.FEMALE, "Maxi", "Muster", 22),
				new Person(Sex.MALE, "Mäxchen", "Muster", 4)});
		
		persons.forEach(System.out::println);
		// [sex: MALE; firstname: Max; lastname: Muster; age: 25]
		// [sex: FEMALE; firstname: Maxi; lastname: Muster; age: 22]
		// [sex: MALE; firstname: Mäxchen; lastname: Muster; age: 4]

		debugNextStageWithLineSeperator(testStep++);
		
		persons.forEach(person -> System.out.println(person));
		// [sex: MALE; firstname: Max; lastname: Muster; age: 25]
		// [sex: FEMALE; firstname: Maxi; lastname: Muster; age: 22]
		// [sex: MALE; firstname: Mäxchen; lastname: Muster; age: 4]

		debugNextStageWithLineSeperator(testStep++);
		
		persons.stream().filter(person -> person.getAge() <= 18).forEach(System.out::println);
		// [sex: MALE; firstname: Mäxchen; lastname: Muster; age: 4]

		debugNextStageWithLineSeperator(testStep++);
		
		persons.stream().filter(person -> person.getAge() >= 18 && person.getSex() == Sex.FEMALE)
		                .forEach(person -> printPerson(person));
		// [sex: FEMALE; firstname: Maxi; lastname: Muster; age: 22]

		debugNextStageWithLineSeperator(testStep++);
		
		Integer totalAge = persons.stream().mapToInt(Person::getAge).sum();
		Integer maxAge = persons.stream().mapToInt(Person::getAge).max().getAsInt();
		Integer minAge = persons.stream().mapToInt(Person::getAge).min().getAsInt();
		Integer averageAge = (int) persons.stream().mapToInt(Person::getAge).average().getAsDouble();
		System.out.println("totalAge:   " + totalAge);
		System.out.println("maxAge:     " + maxAge);
		System.out.println("minAge:     " + minAge);
		System.out.println("averageAge: " + averageAge);
		// totalAge:   51
		// maxAge:     25
		// minAge:     4
		// averageAge: 17

		debugNextStageWithLineSeperator(testStep++);

		persons.stream().mapToInt(Person::getAge).sorted().forEach(System.out::println);
		// 4
		// 22
		// 25

		debugNextStageWithLineSeperator(testStep++);

		persons.stream()
		       .sorted((person1, person2) -> Integer.compare(person1.getAge(), person2.getAge()))
		       .forEach(person -> System.out.println(person));
		// [sex: MALE; firstname: Mäxchen; lastname: Muster; age: 4]
		// [sex: FEMALE; firstname: Maxi; lastname: Muster; age: 22]
		// [sex: MALE; firstname: Max; lastname: Muster; age: 25]

		debugNextStageWithLineSeperator(testStep++);
		
		List<String> myList = new ArrayList<String>();
		myList.addAll(Arrays.asList(new String[] { "abc", "", " def ", null, "  ", "ghi" }));
		myList.removeIf( s -> s == null );
		myList.replaceAll( String::trim );
		myList.removeIf( String::isEmpty );
		myList.forEach( System.out::println );		
		// abc
		// def
		// ghi

		debugNextStageWithLineSeperator(testStep++);
		
		Stream.of(1, 2, 3, 4).forEach( (x) -> { 
			System. out. println("forEach: " + x);
		}) ;		
		// forEach: 1
		// forEach: 2
		// forEach: 3
		// forEach: 4

		debugNextStageWithLineSeperator(testStep++);
		
		Map<Boolean, List<Integer>> even = Stream.of(1, 2, 3, 4).collect(
				Collectors. groupingBy( i -> i % 2 == 0) );
		System.out.print(even);
		// {false=[1, 3], true=[2, 4]}
		
	}
	
	public static void printPerson(Person person) {
		System.out.println(person);
	}
	
	private static void debugNextStageWithLineSeperator(int number) {
		System.out.println("\n------------------------------------------");
		System.out.println("Test " + number + ":"); 
		System.out.println("------------------------------------------"); 
	}
}
	

class Person


package de.snowbits.j8;

public class Person {
	
	public enum Sex {
		MALE, FEMALE
	}
	
	private Sex _sex;
	private String _firstname;
	private String _lastname;
	private int _age;
	
	public Person(Sex sex, String firstname, String lastname, int age) {
		_sex = sex;
		_firstname = firstname;
		_lastname = lastname;
		_age = age;
	}
	
	public Sex getSex() {
		return _sex;
	}
	
	public String getFirstname() {
		return _firstname;
	}

	public String getLastname() {
		return _lastname;
	}

	public int getAge() {
		return _age;
	}
	
	@Override
	public String toString() {
		return new StringBuilder()
			.append("[sex: ").append(getSex())
			.append("; firstname: ").append(getFirstname())
			.append("; lastname: ").append(getLastname())
			.append("; age: ").append(getAge())
			.append("]")
			.toString();
	}

}	
	

class Calculator


package de.snowbits.j8;


public class Calculator {
	
    public static final DoubleMath addition       = (a, b) -> a + b;
    public static final DoubleMath subtraction    = (a, b) -> a - b;
    public static final DoubleMath multiplication = (a, b) -> a * b;
    public static final DoubleMath division       = (a, b) -> a / b;
    
    public static void main(String[] args) {
        Calculator calc = new Calculator();
    	double x = 50d;
    	double y = 25d;
        
        System.out.println(x + " + " + y + " = " + calc.operate(addition, x, y));
        System.out.println(x + " - " + y + " = " + calc.operate(subtraction, x, y));
        System.out.println(x + " * " + y + " = " + calc.operate(multiplication, x, y));
        System.out.println(x + " : " + y + " = " + calc.operate(division, x, y));
        // 50.0 + 25.0 = 75.0
        // 50.0 - 25.0 = 25.0
        // 50.0 * 25.0 = 1250.0
        // 50.0 : 25.0 = 2.0         
    }
        
    public double operate(DoubleMath doubleMath, double a, double b) {
        return doubleMath.operation(a, b);
    }

    public interface DoubleMath {
    	double operation(double a, double b);   
    }
    
}

	

Syntax für Lambda-Ausdrücke

Syntax Regel
Parameterlisten
  (int x) -> x + 1 Parameterliste mit einem Parameter und expliziter Typangabe
falsch int x -> x + 1 Parameterliste mit Typangabe stets in Klammern
  (x) -> x + 1 Parameterliste mit einem Parameter ohne explizite Typangabe
  x -> x + 1 Parameterliste mit einem Parameter ohne explizite Typangabe: Klammern dürfen weggelassen werden
  (int x, short y) -> x + y Parameterliste mit zwei Parametern und expliziten Typangaben
falsch int x, short y -> x + y Parameterliste mit Typangaben stets in Klammern
  (x, y) -> x + y Parameterliste mit zwei Parametern ohne explizite Typangaben
falsch (x, short y) -> x + y keine Mischung von Parametern mit und ohne explizite Typangabe
  () -> 42 Parameterliste darf leer sein
Funktionenrümpfe
  (x,y) -> x * x - y * y Rumpf mit nur einem Ausdruck
  x -> {
    . . Anweisungen; . . .
   return wert;
}
Rumpf als Block mit mehreren Anweisungen und abschließender return-Anweisung
falsch (int x) -> return x + 1 die return-Anweisung nur innerhalb eines Blocks mit geschweiften Klammern { ... }

Wichtigste funktionalen Interfaces

Interface Lambda-Ausdruck Auswertungsmethode Bemerkung
Consumer<T> (T x) -> const; accept(T x) ein Parameter, keine Rückgabe
Supplier<T> () -> const; get() kein Parameter, Rückgabe vom Typ T
Predicate<T> x -> x < 5; test(T x) ein Parameter vom Typ T, Rückgabe vom Typ boolean
Function<T,R> x -> x * x - x + 1; apply(T x) ein Parameter vom Typ T, Rückgabe vom Typ R
BiFunction<T,U,R> (x,y) -> x * x - y * y; apply(T x, U y) zwei Parameter vom Typ T und U, Rückgabe vom Typ R

Sample1.java


package de.snowbits.j8;

import java.util.stream.IntStream;

public class Sample1 {

	public static void main(String[] args) {
		System.out.println("isPrime: " + isPrime(1));
		System.out.println("isPrime: " + isPrime(2));
		System.out.println("isPrime: " + isPrime(3));
		System.out.println("isPrime: " + isPrime(4));
		System.out.println("--- ");
		System.out.println("isPrimeJava8: " + isPrimeJava8(1));
		System.out.println("isPrimeJava8: " + isPrimeJava8(2));
		System.out.println("isPrimeJava8: " + isPrimeJava8(3));
		System.out.println("isPrimeJava8: " + isPrimeJava8(4));
	}
	
	private static boolean isPrime(final int number) {
		for (int i = 2; i < number; i++) {
			if (number % i == 0) 
				return false;
		}

		return number > 1;
	}
	
	private static boolean isPrimeJava8(final int number) {
		return number > 1 && IntStream.range(2,  number)
				.noneMatch(index -> number % index == 0);
	}	
}
	

Ausgabe


isPrime: false
isPrime: true
isPrime: true
isPrime: false
--- 
isPrimeJava8: false
isPrimeJava8: true
isPrimeJava8: true
isPrimeJava8: false
	

Sample2.java


package de.snowbits.j8;

import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;

public class Sample2 {
	
	public static final boolean isGreaterThan3(int number) {
		System.out.println("isGreaterThan3: " + number);
		return number > 3;
	}
	
	public static final boolean isEven(int number) {
		System.out.println("isEven: " + number);
		return number > 3 && number % 2 == 0;
	}
	
	public static final int doubleIt(int number) {
		System.out.println("doubleIt: " + number);
		return number * 2;
	}
	
	public static void main(String[] args) {
		// java
		List<Integer> values = Arrays.asList(1, 2, 3, 5, 4, 6, 7, 8, 9, 10);
		int result = 0;
		
		for (Integer element : values) {
			if (element > 3 && element % 2 == 0) {
				result = element * 2;
				break;
			}
		}
		
		System.out.println("java: " + result);
		System.out.println("--- ");
		
		// java 8 Lösung 1
		System.out.println("java 8 L-1: " +
				values.stream()
                                      .filter(e -> e > 3)
                                      .filter(e -> e % 2 == 0)
                                      .map(e -> e * 2)
                                      .findFirst()
		);
		System.out.println("--- ");
		
		// java 8 Lösung 2
		final Stream<Integer> temp = values.stream()
                                                     .filter(Sample2::isGreaterThan3)
                                                     .filter(Sample2::isEven)
                                                     .map(Sample2::doubleIt);
		System.out.println("java 8 L-2: " + temp.findFirst());
		System.out.println("--- ");
		
		// java 8 Lösung 3
		Predicate<Integer> isGreaterThan3 = number -> number > 3;
		Predicate<Integer> isEven = number -> number % 2 == 0;
		Function<Integer, Integer> doubleIt = number -> number * 2;
		
		final Stream<Integer> temp3 = values.stream()
                                                     .filter(isGreaterThan3)
                                                     .filter(isEven)
                                                     .map(doubleIt);
		System.out.println("java 8 L-3: " + temp3.findFirst());		
	}
}
	

Ausgabe


java: 8
--- 
java 8 L-1: Optional[8]
--- 
isGreaterThan3: 1
isGreaterThan3: 2
isGreaterThan3: 3
isGreaterThan3: 5
isEven: 5
isGreaterThan3: 4
isEven: 4
doubleIt: 4
java 8 L-2: Optional[8]
--- 
java 8 L-3: Optional[8]
	

Sample3.java


package de.snowbits.j8;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

interface Selector {
	boolean pick(int number);
}

public class Sample3 {

	public static void main(String[] args) {
		List<Integer> values = Arrays.asList(1, 2, 3, 5, 4, 6, 7, 8, 9, 10);
		System.out.println("totalValues: " + totalValues(values));
		System.out.println("totalValues selector: " + totalValues(values, e -> true));
		System.out.println("totalValues selector even: " + totalValues(values, e -> e % 2 == 0));
		System.out.println("totalValues2 selector even: " + totalValues2(values, e -> e % 2 == 0));		
	}
	
	public static final int totalValues(List<Integer> numbers) {
		int result = 0;
		
		for (int element : numbers) {
			result += element;
		}
		
		return result;
	}
	
	public static final int totalValues(List<Integer> numbers, Selector selector) {
		int result = 0;
		
		for (int element : numbers) {
			if (selector.pick(element))
				result += element;
		}
		
		return result;
	}	
	
	public static final int totalValues2(List<Integer> numbers, Predicate<Integer> selector) {
		return numbers.stream()
				.filter(selector)
				.reduce(0, Math::addExact);
	}
}
	

Ausgabe


totalValues: 55
totalValues selector: 55
totalValues selector even: 30
totalValues2 selector even: 30
	

Top


Example
Sitemap Kontakt Impressum