Publicité
+ Répondre à la discussion Actualité déjà publiée
Page 2 sur 2 PremièrePremière 12
Affichage des résultats 21 à 39 sur 39
  1. #21
    Membre Expert
    Avatar de la.lune
    Homme Profil pro Bilal Soidik
    Développeur informatique
    Inscrit en
    décembre 2010
    Messages
    424
    Détails du profil
    Informations personnelles :
    Nom : Homme Bilal Soidik

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2010
    Messages : 424
    Points : 1 354
    Points
    1 354

    Par défaut

    adiGuba

  2. #22
    Expert Confirmé Sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    avril 2002
    Messages
    13 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : avril 2002
    Messages : 13 026
    Points : 20 808
    Points
    20 808

    Par défaut

    Je viens de découvrir autre chose concernant les interfaces.




    Pour rappel il y a les "default methods" qui permettront d'intégrer du code dans les interfaces :
    Code :
    1
    2
    3
    4
    5
    6
    7
    public interface Demo {
        public void method1();
     
        public default void method2() {
             System.out.println("method2");
        }
    }
    Les classes qui implémentent cette interface pourront se contenter d'implémenter la méthode method1().
    La méthode method2() est optionnelle et utilisera le code par défaut si elle n'est pas implémenté par la classe.







    Mais ce n'est pas tout, on pourra utiliser des méthodes private, destiné à être utiliser dans les "default methods" afin de pouvoir mutualiser le code.
    Par exemple :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public interface Demo {
        public void method1();
     
        public default void method2() {
    	this.print("method2");
        }
     
        public default void method3() {
    	this.print("method3");
        }
     
        private void print(String text) {
             System.out.println(text);
        }
    }





    Enfin les interfaces pourront contenir des méthodes static :
    Code :
    1
    2
    3
    4
    5
    public interface Demo {
        public static void method() {
    	/* ... */
        }
    }

    Attention toutefois car à l'heure actuelle ceci n'est implémenté que dans le compilateur. En clair cela va compiler normalement, mais cela risque de générer des erreurs à l'exécution...


    Sources :
    Enhancement: Add support for static interface methods
    Enhancement: Add experimental support for private (instance) interface methods


    a++

  3. #23
    Expert Confirmé Sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    avril 2002
    Messages
    13 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : avril 2002
    Messages : 13 026
    Points : 20 808
    Points
    20 808

    Par défaut

    Citation Envoyé par la.lune Voir le message
    Là on vient d'apprendre l'ajout du mot clé "default"
    C'est le principe des "default's methods" qui permet de définir une implémentation par défaut dans une interface. Les classes qui l'implémente n'auront pas l'obligation d'implémenter la méthode.


    Cette notion a eu plusieurs noms, et j'en ai pas mal parlé sur mon blog :


    Citation Envoyé par la.lune Voir le message
    mais peut-on avoir une méthode par défaut et static aussi?
    Cela n'a pas de sens.
    Les méthodes static d'une interface ne sont pas hérité ni rien. Elle doivent impérativement être appelé via la syntaxe NomDeLinterface.method().



    a++

  4. #24
    Membre émérite Avatar de Gugelhupf
    Homme Profil pro
    Développeur informatique
    Inscrit en
    décembre 2011
    Messages
    483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : décembre 2011
    Messages : 483
    Points : 842
    Points
    842

    Par défaut Différence entre nouvel interface et les classes abstraites ?

    Bonjour,

    abiGuba, quels seront les différences entre ces interfaces et une classe abstraite ?

    Est-ce que c'est semblable aux Traits et Mixins ?

    Comment résoudre le problème d'héritage multiple si une classe implémente 2 interfaces qui contiennent une méthode defaut avec le même nom mais un contenu différent ?

  5. #25
    Membre éclairé
    Homme Profil pro Anthony
    Java Analyst Developer
    Inscrit en
    mai 2011
    Messages
    129
    Détails du profil
    Informations personnelles :
    Nom : Homme Anthony
    Âge : 24
    Localisation : Belgique

    Informations professionnelles :
    Activité : Java Analyst Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : mai 2011
    Messages : 129
    Points : 346
    Points
    346

    Par défaut

    Citation Envoyé par Gugelhupf Voir le message
    Bonjour,

    abiGuba, quels seront les différences entre ces interfaces et une classe abstraite ?

    Est-ce que c'est semblable aux Traits et Mixins ?

    Comment résoudre le problème d'héritage multiple si une classe implémente 2 interfaces qui contiennent une méthode defaut avec le même nom mais un contenu différent ?
    Ca ne compilera pas tout simplement car le compilo te dira automatiquement que ta classe fille qui implémente les deux interfaces possèdes deux fois la même méthodes ;-)

  6. #26
    Membre émérite Avatar de Gugelhupf
    Homme Profil pro
    Développeur informatique
    Inscrit en
    décembre 2011
    Messages
    483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : décembre 2011
    Messages : 483
    Points : 842
    Points
    842

    Par défaut

    Ça parait logique de ce point de vue, mais alors pourquoi la compilation est autorisée en C++ ? ...

    Aussi quel différence y a-t-il maintenant entre une interface et une classe abstraite ?
    Pour moi une interface était une classe 100% abstraite, je vais devoir changer ma définition de la chose.

  7. #27
    Expert Confirmé Sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    avril 2002
    Messages
    13 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : avril 2002
    Messages : 13 026
    Points : 20 808
    Points
    20 808

    Par défaut

    Citation Envoyé par Gugelhupf Voir le message
    abiGuba, quels seront les différences entre ces interfaces et une classe abstraite ?
    Les interfaces ne peuvent pas contenir d'état car elles ne peuvent pas contenir d'attribut d'instance.



    Citation Envoyé par Gugelhupf Voir le message
    Est-ce que c'est semblable aux Traits et Mixins ?
    Oui cela s'en approche beaucoup.



    Citation Envoyé par Gugelhupf Voir le message
    Comment résoudre le problème d'héritage multiple si une classe implémente 2 interfaces qui contiennent une méthode defaut avec le même nom mais un contenu différent ?
    S'il n'y a aucun lien entre les deux interfaces, cela provoquera une erreur de compilation. Il faudra alors l'implémenter.
    On peut bien sûr se contenter de réutiliser une implémentation d'une interface via une syntaxe spécifique, par exemple :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    interface A {
        public default void method() {
            System.out.println("A::method");
        }
    }
     
    interface B {
        public default void method() {
            System.out.println("B::method");
        }
    }
     
    class C implements A, B {
    	public void method() {
    		A.super.method();
    	}
    }

    Par contre les règles sont plus souples, car si la méthode est implémenter dans une classe parente, cela prendra toujours la priorité sur les méthodes par défaut, qui comme leur nom l'indique, ne seront utilisé QUE dans le cas où la classe ne possèdent pas d'implémentation.



    Là où cela est très intéressant, c'est que la résolution de la méthode est géré par la JVM au runtime. C'est à dire que cela permet d'ajouter une méthode à une interface sans avoir à recompiler toutes les classes qui l'implémentent...



    Citation Envoyé par Gugelhupf Voir le message
    Ça parait logique de ce point de vue, mais alors pourquoi la compilation est autorisée en C++ ? ...
    Les règles d'héritage du C++ et de Java sont très différente.
    En Java toutes les méthodes sont implicitement virtuelles et donc hérités par défaut, alors que c'est exactement l'inverse en C++.
    Du coup les problèmes que l'on peut rencontrer via l'héritage multiple sont moins visible...


    a++

  8. #28
    Membre Expert
    Avatar de la.lune
    Homme Profil pro Bilal Soidik
    Développeur informatique
    Inscrit en
    décembre 2010
    Messages
    424
    Détails du profil
    Informations personnelles :
    Nom : Homme Bilal Soidik

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2010
    Messages : 424
    Points : 1 354
    Points
    1 354

    Par défaut

    Citation Envoyé par adiGuba Voir le message
    Mieux encore, lorsqu'on se contente d’appeler une méthode, et que sa signature correspond à l'interface fonctionnelle, on peut remplacer l'expression Lambda par un pointeur de méthode (notez bien les doubles deux-points :: )
    Code :
            iterable.forEach(System.out::println);
    J'ai une question ici, d'abord je comprend bien le comportement de cette expression, mais ma question c'est que veux-tu dire par 'interface fonctionnelle'? Tu peux détailler un peu pour qu'on comprenne le concept, je vais être un peut claire, si j'ai une interface que j'ai crée et une méthode static avec paramètre un objet, dont " iterable" itère sur une une collection de ces objets. alors peut-on faire cet astuce?

    Je donne un code exemple:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    public class A{
    .....
    }
    public interface I {
     
    public static void methode(A a){
    .....
    }}//interface I
     
    //Et puis dans un traitement peux-je faire:
     
    Iterable<A> iterable = ...
     
     iterable.forEach(I::methode)
    Je pense que ma question est claire

  9. #29
    Expert Confirmé Sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    avril 2002
    Messages
    13 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : avril 2002
    Messages : 13 026
    Points : 20 808
    Points
    20 808

    Par défaut

    @la.lune
    Réponse courte : oui ton code fonctionne


    Réponse longue :

    Une interface fonctionnelle c'est juste une interface qui ne contient qu'une seule et unique méthode abstraite (sans compter les "default's methods" donc), comme par exemple Runnable.

    Les lambdas et les références de méthode ne peuvent être convertis qu'en une interface fonctionnelle, à condition que leurs signatures correspondent.


    Par exemple dans ce cas là la méthode Iterable::forEach() est définie comme ceci :
    Code :
    1
    2
    3
    4
    5
        public default void forEach(Block<? super T> block) {
            for (T t : this) {
                block.accept(t);
            }
        }
    Et Block fait partie du package java.util.function, qui inclut un ensemble d'interface fonctionnelle basique...
    Grosso-modo elle est définie comme ceci :
    Code :
    1
    2
    3
    4
    5
    public interface Block<T> {
     
        public void accept(T t); 
     
    }
    Et c'est la signature de cette méthode qu'il faudra donc respecter avec la lambda (ou la référence de méthode).


    Si tu références une méthode static, alors la signature de cette méthode devra correspondre à la signature de l'interface. C'est le cas dans ton exemple donc cela marchera bien

    Après tu as encore le cas particulier des méthodes d'instances, où tu as deux possibilités :
    • Si tu références une méthode d'instance via son type, et la signature est alors modifié en rajoutant le type en tant que premier paramètre, ce qui permettra de passer l'instance lors de l'appel.
    • Si tu la référence via une instance d'un objet, la signature n'est pas modifié et l'appel se fera sur l'instance indiqué.



    Exemple Object::toString pourra être associer avec une interface fonctionnelle tel quel celle-ci :
    Code :
    1
    2
    3
    public interface Exemple {
        public String method(Object o);
    }

    A l'inverse pour une instance d'objet "o", o::toString sera associable avec une interface fonctionnelle comme ceci :
    Code :
    1
    2
    3
    public interface Exemple {
        public String method();
    }


    Je ne sais pas si tout est bien clair...


    a++

  10. #30
    Membre Expert
    Avatar de la.lune
    Homme Profil pro Bilal Soidik
    Développeur informatique
    Inscrit en
    décembre 2010
    Messages
    424
    Détails du profil
    Informations personnelles :
    Nom : Homme Bilal Soidik

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2010
    Messages : 424
    Points : 1 354
    Points
    1 354

    Par défaut

    Oui j'ai compris en grog, même si j'avais fait juste fait une erreur en oubliant le mot "void" pour methode(..).

    Mais là encore juste pour plus de précision, je me demande quelle est l'interface référencé ici quand tu dis "Si tu références une méthode static, alors la signature de cette méthode devra correspondre à la signature de l'interface", En quelle interface fonctionnelle la lamba sera converti?(l'interface dont sa signature correspond à celle de ma méthode static) Je n'ai pas bien saisi, où est la correspondance exactement?

    Aussi, je suis je suis un peu perdu quand tu parles de correspondance entre signature de méthode et signature d'interface, ou bien tu veux parler de correspondance entre signature de méthode et signature de la méthode de l'interface fonctionnelle.

    L'exemple que tu as donné c'est sur une interface fonctionnelle déjà existante, est ce le cas pour les autres? Ce que je n'arrive pas à saisir. Sur tes premières réponses tu parles de méthodes générés dynamiquement, donc si je ne me trompe pas, est-ce ma référence de méthode sera converti dynamiquement en interface fonctionnelle lors de la compilation?

  11. #31
    Expert Confirmé Sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    avril 2002
    Messages
    13 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : avril 2002
    Messages : 13 026
    Points : 20 808
    Points
    20 808

    Par défaut

    Citation Envoyé par la.lune Voir le message
    Aussi, je suis je suis un peu perdu quand tu parles de correspondance entre signature de méthode et signature d'interface, ou bien tu veux parler de correspondance entre signature de méthode et signature de la méthode de l'interface fonctionnelle.
    Oui je voulais bien parler de la signature de la méthode de l'interface fonctionnelle.

    Une lambda (ou une référence de méthode) ne peut être associé qu'à une interface fonctionnelle, et il faut que la signature correspondent à celle de la méthode :

    Par exemple :
    Code :
    ActionListener listener = (ActionEvent e) -> System.out.println("ActionEvent = " + e);
    L'expression lambda a la signature suivante : "void(ActionEvent)", ce qui correspond à la signature de la méthode de l'interface fonctionnelle ActionListener qui défini la méthode suivante :
    Code :
    public void actionPerformed(ActionEvent e);
    Au passage le "Type Inférence" rentre en jeu, ce qui nous permet de ne pas spécifier le type du paramètre dans la lambda :
    Code :
    ActionListener listener = (e) -> System.out.println("ActionEvent = " + e);





    Et c'est la même chose pour les références de méthode. Si on a une méthode définie comme ceci :
    Code :
    1
    2
    3
    public static void onEvent(ActionEvent e) {
        ...
    }
    On peut l'associer à un ActionListener puisque la signature de la méthode concorde bien à la signature void(ActionEvent) :
    Code :
    ActionListener listener = MaClasse::onEvent;


    S'il s'agit d'une méthode d'instance :
    Code :
    1
    2
    3
    4
    5
    6
    public class MaClasse {
     
        public void doSomething(ActionEvent e) {
             ...
        }
    }
    On ne peut pas l'associer comme cela puisque l'instance se rajoute à la signature, qui devient void(MaClasse,ActionEvent).
    Code :
    ActionListener listener = MaClasse::doSomething; // ERREUR
    Pour que la signature corresponde, il faut lui associer une instance, par exemple :
    Code :
    1
    2
    MaClasse cls = new MaClasse();
    ActionListener listener = cls::doSomething; // OK
    Dans ce cas là l'instance ("cls" dans l'exemple) sera utilisée pour l'appel de la méthode, qui conserve du coup sa signature originale...







    Et pour les méthodes c'est la même chose. Les méthodes qui utiliseront les lambdas n'ont rien de spécial, si ce n'est qu'elles utilisent une interface fonctionnelle. Mais même si cette notion est "nouvelle", cela ne l'est pas vraiment car l'API standard est déjà pleine d'interface fonctionnelle...


    Du coup on pourra utiliser les lambdas/références de méthode avec des APIs existante, du moment qu'elles utilisent une interface fonctionnelle :
    Code :
    1
    2
    3
        MaClasse cls = new MaClasse();
        JButton b = new JButton();
        b.addActionListener(cls::doSomething);

    C'est le "Type inference" qui se chargera de vérifier le tout, c'est à dire :
    • Récupérer le type du paramètre de addActionListener() (qui est justement un ActionListener).
    • Vérifier qu'il s'agit bien d'une interface fonctionnelle (ce qui est le cas puisqu'elle ne comporte qu'une seule méthode)
    • Vérifier que la signature de la lambda/référence de méthode concorde bien avec la signature de la méthode de l'interface fonctionnelle.


    Et en cas de surcharge, le compilo ira chercher la version de la méthode qui correspond.




    A noter également l'existence de référence de constructeur (en utilisant ::new), par exemple :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    	// Création d'un ThreadFactory via une classe anonyme :
    	Executors.newCachedThreadPool(new ThreadFactory() {
    		@Override
    		public Thread newThread(Runnable r) {
    			return new Thread(r);
    		}
    	});
     
    	// Création d'un ThreadFactory via une référence de constructeur :
    	Executors.newCachedThreadPool(Thread::new);
    	// Ceci utilisera le constructeur Thread(Runnable),
    	// qui correspond à la signature de la méthode de ThreadFactory

    a++

  12. #32
    Expert Confirmé Sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    avril 2002
    Messages
    13 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : avril 2002
    Messages : 13 026
    Points : 20 808
    Points
    20 808

    Par défaut

    Autre petite subtilité que j'ai découverte aujourd'hui : de nombreuses interfaces fonctionnelles (déjà existante ou non) sont enrichies de "default's method" permettant diverses choses.


    Par exemple pour trier une liste d'User par nom, on pourra utiliser le code suivant :
    Code :
    1
    2
    3
        List<User> list = ....
     
        list.sort( Comparators.comparing(User::getFirstName) );
    Avec Comparators.comparing() qui nous retourne un Comparator<User> basé sur le getter getFirstName().


    Or l'interface Comparator est doté de nouvelle méthode permettant de créer des dérivés.

    Par exemple on peut inverser l'ordre de tri très simplement :
    Code :
    1
    2
    3
     
        list.sort( Comparators.comparing(User::getFirstName)
                .reverseOrder() );
    Ou alors on peut enchainer plusieurs comparaisons qui seront traiter dans l'ordre.
    Par exemple pour tirer par nom, prénom puis date de naissance on pourra faire ceci :
    Code :
    1
    2
    3
        list.sort( Comparators.comparing(User::getFirstName)
                .thenComparing(User::getLastName)
                .thenComparing(User::getBirthday) );


    a++

  13. #33
    Membre Expert
    Avatar de la.lune
    Homme Profil pro Bilal Soidik
    Développeur informatique
    Inscrit en
    décembre 2010
    Messages
    424
    Détails du profil
    Informations personnelles :
    Nom : Homme Bilal Soidik

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2010
    Messages : 424
    Points : 1 354
    Points
    1 354

    Par défaut

    pour l'éclaircissement et merci encore de nous faire part de ces nouveautés . Pour ma question là j'ai bien compris, surtout là je vois que si tu m'avait juste répondu en précisant que la signature de ma méthode satic void methode(A) correspond exactement à la signature de la méthode de l'interface fonctionnelle qu'attend un foreach qui est void(T) j'aurais tout compris et surpasser toutes les ambiguïtés.

    De plus j'ai une autre question sur la parallélisation dont tu as mentionné sur les multiples instruction dont on applique à une collection, alors quand tu dis 'si cela est possible', je me pose la question possible dans le sens où certaines instructions dépendent des précédentes ou dans le sens de la capacité de l'ordinateur de paralléliser, et là aussi il y a deux option soit de la parallélisation juste en différents thread qui serait optimisée avec les architectures multi-core ou bien de la vrai parallélisation.

    Ma dernière question c'est que tu parles d'interfaces de types qui ne sont pas encore finalisés dans une de tes réponses, alors peux-tu nous donner plus de détailles sur l'objet de ces interfaces et leur domaines d'applications.

  14. #34
    Expert Confirmé Sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    avril 2002
    Messages
    13 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : avril 2002
    Messages : 13 026
    Points : 20 808
    Points
    20 808

    Par défaut

    Citation Envoyé par la.lune Voir le message
    De plus j'ai une autre question sur la parallélisation dont tu as mentionné sur les multiples instruction dont on applique à une collection,
    Juste une remarque : les opérations s'appliquent sur le flux (stream), mais n'affecte pas la collection en elle-même

    Citation Envoyé par la.lune Voir le message
    alors quand tu dis 'si cela est possible', je me pose la question possible dans le sens où certaines instructions dépendent des précédentes ou dans le sens de la capacité de l'ordinateur de paralléliser, et là aussi il y a deux option soit de la parallélisation juste en différents thread qui serait optimisée avec les architectures multi-core ou bien de la vrai parallélisation.
    C'est juste que cela dépend des instructions que tu utilises, et de ce que tu veux faire.

    Par exemple si tu veux stocker le résultat dans une collection, il faut que cette dernière soit thread-safe, car si ce n'est pas le cas cela engendrera des erreurs. Du coup même si tu choisis un stream parallel ce type d'opération sera en séquentiel par défaut (en fait c'est l'implémentation de la collection qui peut modifier cela).




    Citation Envoyé par la.lune Voir le message
    Ma dernière question c'est que tu parles d'interfaces de types qui ne sont pas encore finalisés dans une de tes réponses, alors peux-tu nous donner plus de détailles sur l'objet de ces interfaces et leur domaines d'applications.
    En fait c'est juste un nouveau package java.util.function qui les interfaces fonctionnelles les plus courante.

    Quelques exemples :

    Block<T> qui permet d'exécuter un bout de code en prenant un objet en paramètre (c'est ce qui est utiliser par forEach() par exemple) :
    Code :
    1
    2
    3
    public interface Block<T> {
    	public void accept(T t);
    }
    Function<T, R> qui prend un paramètre T et retourne une valeur R.
    Code :
    1
    2
    3
    public interface Function<T, R> {
    	public R apply(T t);
    }
    Predicate<T> qui permet de tester un élément.
    Code :
    1
    2
    3
    public interface Predicate<T> {
        public boolean test(T t);
    }
    Supplier<T> qui permet de fournir une valeur.
    Code :
    1
    2
    3
    public interface Supplier<T> {
        public T get();
    }
    etc...



    On y retrouve aussi des versions optimisés pour les types primitifs, ou des versions "Bi" prenant deux paramètres (et utilisé par les Map pour les clef/valeur).


    Il n'y a rien d'exceptionnel là dedans, c'est juste pour fournir une base commune qui sera utilisable par tout le monde plutôt que de réécrire tout plein d'interface similaire dans chaque API



    a++

  15. #35
    Membre Expert
    Avatar de la.lune
    Homme Profil pro Bilal Soidik
    Développeur informatique
    Inscrit en
    décembre 2010
    Messages
    424
    Détails du profil
    Informations personnelles :
    Nom : Homme Bilal Soidik

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : décembre 2010
    Messages : 424
    Points : 1 354
    Points
    1 354

    Par défaut

    pour ces réponses.
    Là tu vient de m'éclairer sur ces fonctions. Merci aussi pour le lien, je vois bien les détailles sur ces fonctions. Vraiment j'ai hâte de voir la sortie de la JVM 1.8 pour commencer à coder nos programmes avec ces fonctionnalités très intéressantes, on aura à écrire peu de code, et surtout nous le fan de javafx on aura à tout simplifier lors de la sortie de Javafx 8 avec le JSE8 ( déjà la date est-elle officialisée pour quand?) . Là si j'ai bien compris à présent le boulot c'est de maîtriser aussi ces interfaces à utiliser pour écrire de bon expressions lambda(ou référence de méthode) et les autres interfaces.

    On va bien voir la grande utilité dans des milliers de lignes de codes qui seront réduits disons jusqu’à 40% (possible). De plus ceci permettra aussi de bien structurer l'architecture du programme, on crée les interfaces( et leur implémentation si on) à part et fait les traitement à part en faisant référence aux méthodes. En tout cas c'est une évolution marquante du langage.

  16. #36
    Expert Confirmé Sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    avril 2002
    Messages
    13 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : avril 2002
    Messages : 13 026
    Points : 20 808
    Points
    20 808

    Par défaut

    Il y a un nouveau build du JDK8/Lambda : http://jdk8.java.net/lambda/


    Je n'ai pas vraiment eu le temps de le parcourir, mais l'interface Map s'est enrichie de plusieurs méthodes par défaut, en plus du forEach() dont j'avais déjà parlé !
    Rien d'extraordinaire en soit, mais quand même des méthodes bien utile :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    	/*
    	 * Supprime un couple clef/valeur,
    	 * seulement si le couple existe.
    	 */
    	map.remove("KEY", "VALUE");
     
    	/*
    	 * Remplace la valeur associé à la clef,
    	 * seulement si cette clef existe déjà.
    	 */
    	map.replace("KEY", "NEWVALUE");
     
    	/*
    	 * Remplace la valeur d'un couple clef/valeur
    	 * seulement si le couple existe.
    	 */
    	map.replace("KEY", "VALUE", "NEWVALUE");
     
    	/*
    	 * Remplace toutes les valeurs de la Map,
    	 * par le résultat de l'expression.
    	 * Exemple : mettre toutes les valeurs en Majuscule :
    	 */
    	map.replaceAll((k,v) -> v.toUpperCase());
     
    	/*
    	 * Ajoute un couple clef/valeur,
    	 * seulement si la clef n'est pas déjà présente.
    	 */
    	map.putIfAbsent("KEY", "VALUE");
     
    	/*
    	 * Permet de récupérer ET de modifier
    	 * la valeur d'une clef dans la Map.
    	 */
    	String value = map.compute("KEY", (k,v) -> v.toUpperCase());
     
    	/*
    	 * Permet de modifier la valeur d'une clef,
    	 * seulement si le couple clef/valeur existe.
    	 */
    	String value = map.computeIfPresent("KEY", (k,v)->"new value");
     
    	/*
    	 * Permet de définir la valeur d'une clef,
    	 * lorsque le couple clef/valeur est absent.
    	 * Sinon on récupère la valeur existante.
    	 */
    	String value = map.computeIfAbsent("KEY", (k)->"empty");

    A noter que ce "computeIfAbsent()" nous permettra d'implémenter une MultiMap en un rien de temps :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class MultiMap<K,V> extends HashMap<K,Collection<V>> {
     
    	private Collection<V> creator(K key) {
    		return new ArrayList<>();
    	}
     
    	public void add(K key, V value) {
    		this.computeIfAbsent(key, this::creator).add(value);
    	}
    }
    L'appel add(K,V) permettra d'ajouter l'élément "value" dans la collection, en la créant si neccessaire.


    a++

  17. #37
    Membre émérite Avatar de Gugelhupf
    Homme Profil pro
    Développeur informatique
    Inscrit en
    décembre 2011
    Messages
    483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : décembre 2011
    Messages : 483
    Points : 842
    Points
    842

    Par défaut

    Bonjour,

    Je lu l'article sur la syntaxe des lambdas (écrit par adiGuba).

    1. J'aurais aimé savoir s'il y avait une différence entre le fait de préciser le type d'un argument ou non :
    Code :
    1
    2
    3
    4
    5
    // On ne précise pas le int
    (x) -> x + 1 
     
    // On précise le int
    (int x) -> x + 1


    2. Aussi, si on utilise un lambda dans une classe, pourra-t-on automatiquement avoir accès au this dans le lambda (sans avoir à le faire passer par un paramètre) ?



    En C++11 ou PHP5.3 il est possible de faire passer des variables externes au bloc lambda, on fait alors la distinction entre fonction anonyme et fermeture du lambda.

    En C++11 par exemple :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // On retourne x + y
    [](int x, int y) -> int {
        return x + y;
    };
     
    // On retourne x + y + z (z variable extérieur au bloc lambda)
    int z = 10;
    [z](int x, int y) -> int {
        return x + y + z;
    };
    En PHP5.3 par exemple :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?php 
    // On retourne x + y
    function($x, $y){
        return $x + $y;
    };
     
    // On retourne x + y + z (z variable extérieur au bloc lambda)
    $z = 10;
    function($x, $y) use ($z){
        return $x + $y + $z;
    };
    3. Qu'en est-t-il du Java pour les fermetures (utilisation de variable extérieur au bloc lambda) ?


    Merci

  18. #38
    Expert Confirmé Sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    avril 2002
    Messages
    13 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : avril 2002
    Messages : 13 026
    Points : 20 808
    Points
    20 808

    Par défaut

    Citation Envoyé par Gugelhupf Voir le message
    1. J'aurais aimé savoir s'il y avait une différence entre le fait de préciser le type d'un argument ou non :
    Il n'y a aucune différence. S'il n'est pas précisé le type est déduite selon le contexte par le compilateur...



    Citation Envoyé par Gugelhupf Voir le message
    2. Aussi, si on utilise un lambda dans une classe, pourra-t-on automatiquement avoir accès au this dans le lambda (sans avoir à le faire passer par un paramètre) ?
    Oui, tout simplement en utilisant this :
    Code :
    Runnable r = () -> this.method();

    Citation Envoyé par Gugelhupf Voir le message
    3. Qu'en est-t-il du Java pour les fermetures (utilisation de variable extérieur au bloc lambda) ?
    C'est tout à fait possible :
    Code :
    1
    2
    3
    4
    5
    6
    // On retourne x + y
    IntBinatyOperator op1 = (x, y) -> x + y;
     
    // On retourne x + y + z (z variable extérieur au bloc lambda)
    int z = 10;
    IntBinatyOperator op1 = (x, y) -> x + y + z;
    La seule restriction c'est que la variable doit être implicitement final.
    C'est à dire que la variable doit être définie et ne doit pas être modifié dans la lambda ou en dehors...


    a++

  19. #39
    Membre émérite Avatar de Gugelhupf
    Homme Profil pro
    Développeur informatique
    Inscrit en
    décembre 2011
    Messages
    483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : décembre 2011
    Messages : 483
    Points : 842
    Points
    842

    Par défaut

    Merci beaucoup adiGuba

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •