import java.util.function.*; import java.util.*; class Truc{ public int a; public Truc(int xx){a=xx;} public Truc(String s){a=10;} public String toString(){ return ""+a; } } class Test{ public static void main(String[] args){ ///////////////////////////////////////////////////////////////////////////////// ////// ex basiques ///////////////////////////////////////////////////////////////////////////////// //////////////////// // interface runnable //////////////////// //ex de definition d'une interface fonctionnelle avec une classe anonyme //noter syntaxe "étrange" "new Runnable()" alors que c'est une interface Runnable r = new Runnable(){ public void run(){ System.out.println("Hello, Lambda!"); } }; r.run(); //ex de definition d'une interface fonctionnelle avec une lambda expression Runnable r2 = () -> System.out.println("Hello, Lambda!2"); r2.run(); //////////////////// // interface predicate //////////////////// //en classes anonyme Predicate isEvenV0 = new Predicate(){ //là c'est ok public boolean test(Integer x){ return x%2==1; } }; System.out.println(isEvenV0.test(6)); //avec Lambda expresion Predicate isEven = num -> num % 2 == 0; System.out.println(isEven.test(4)); // true //System.out.println((x -> x%2 == 1).test(4)); // pas ok, car java ne peut pas deviner le type du predicate //////////////////// // interface comparator (utile car vous vous en servez souvent) //////////////////// //avec lambda TreeSet set = new TreeSet<>((t1,t2) -> t2.a - t1.a); set.add(new Truc(5)); set.add(new Truc(2)); set.add(new Truc(7)); for(Truc t : set){ System.out.println(t); } //////////////////// // interface consumer (utile car utilisable dans un forEach, forEach qui sera aussi utilisable avec des stream) //////////////////// Consumer c = (name -> System.out.println("I accepted : "+name)); c.accept("bonjour"); //I accepted bonjour Consumer c2 = new Consumer<>(){ public void accept(String s){ System.out.println("v2 I accepted : "+s); } }; c2.accept("bonjour"); //v2 I accepted bonjour List names = Arrays.asList("Alice", "Bob", "Charlie"); names.forEach(c); ///////////////////////////////////////////////////////////////////////////////// ////// ex avec utilisation d'une var locale ///////////////////////////////////////////////////////////////////////////////// List numbers = Arrays.asList(1, 2, 3, 4, 5); List evens = new ArrayList<>(); numbers.forEach(n -> { if (n % 2 == 0) { evens.add(n); } }); System.out.println("les pairs de numbers: " + evens); //equivalent à : numbers.forEach(new Consumer() { @Override public void accept(Integer n) { if (n % 2 == 0) { evens.add(n); } } }); //attention les variables locales utilisées sont finales, donc le code suivant ne compile pas // int count = 0; // numbers.forEach(n -> { // if (n % 2 == 0) { // count++; // error: Variable used in lambda should be final or effectively final // } // }); } } /// possible d'utiliser un attribut non final class InstanceVariableExample { private int x; public void countEvenNumbers(List numbers) { numbers.forEach(n -> { // Lambda expression qui accède à un attribut pas final if (n % 2 == 0) { x++; } }); } } ///////////////////////////////////////////////// /// exemple classe anonyme ///////////////////////////////////////////////// /// // exemple tiré du projet pokemon, // on pourrait créer une classe par attaque, mais on se retrouverai avec bcp de telles classes, // et une telle classe n'est utilisée qu'à un endroit (au moment de créer un pokémon quand on rajoute son attaque) // -> dans ce type de cas, la classe n'a pas besoin de porter de nom car on n'y réfère qu'une fois donc .. classe anonyme ! // -> on observe syntaxe new CLASSEABSTRAITE(....) // -> on ne peut pas avoir d'attribut // -> on peut se définir d'autres méthodes // -> classe anonyme possible meme pour hériter d'une classe pas abstraite (Attaque pourrait ne pas etre abstraite) abstract class Attaque{ String nom; int dmg; public Attaque(String n, int d){ nom=n; dmg=d; } public void attaquer(){ System.out.println(nom + " " + dmg); } } class TestAttaque{ public static void main(String[] args){ List l = new ArrayList(); l.add( new Attaque("coup", 10){ public void methodeSuppl(){ System.out.println("met dupl"); } public void attaquer(){ methodeSuppl(); super.attaquer(); super.attaquer(); } } ); for(Attaque a : l){ a.attaquer(); } } }