IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

JavaOne 2012 : Oracle renouvelle son engagement à faire évoluer Java et dévoile ses plans


Sujet :

Java

  1. #21
    Membre chevronné
    Avatar de la.lune
    Homme Profil pro
    Directeur Technique
    Inscrit en
    Décembre 2010
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Comores

    Informations professionnelles :
    Activité : Directeur Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2010
    Messages : 545
    Points : 2 084
    Points
    2 084
    Par défaut
    adiGuba

  2. #22
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    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 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    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 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    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
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 320
    Points : 3 740
    Points
    3 740
    Billets dans le blog
    12
    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 ?
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  5. #25
    Membre averti
    Homme Profil pro
    Java
    Inscrit en
    Mai 2011
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Mai 2011
    Messages : 170
    Points : 444
    Points
    444
    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
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 320
    Points : 3 740
    Points
    3 740
    Billets dans le blog
    12
    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.
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  7. #27
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    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 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 chevronné
    Avatar de la.lune
    Homme Profil pro
    Directeur Technique
    Inscrit en
    Décembre 2010
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Comores

    Informations professionnelles :
    Activité : Directeur Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2010
    Messages : 545
    Points : 2 084
    Points
    2 084
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
            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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    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 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public interface Exemple {
        public String method();
    }


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


    a++

  10. #30
    Membre chevronné
    Avatar de la.lune
    Homme Profil pro
    Directeur Technique
    Inscrit en
    Décembre 2010
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Comores

    Informations professionnelles :
    Activité : Directeur Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2010
    Messages : 545
    Points : 2 084
    Points
    2 084
    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 éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    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 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    ActionListener listener = MaClasse::onEvent;


    S'il s'agit d'une méthode d'instance :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    ActionListener listener = MaClasse::doSomething; // ERREUR
    Pour que la signature corresponde, il faut lui associer une instance, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    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 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        list.sort( Comparators.comparing(User::getFirstName)
                .thenComparing(User::getLastName)
                .thenComparing(User::getBirthday) );


    a++

  13. #33
    Membre chevronné
    Avatar de la.lune
    Homme Profil pro
    Directeur Technique
    Inscrit en
    Décembre 2010
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Comores

    Informations professionnelles :
    Activité : Directeur Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2010
    Messages : 545
    Points : 2 084
    Points
    2 084
    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 éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    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 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public interface Function<T, R> {
    	public R apply(T t);
    }
    Predicate<T> qui permet de tester un élément.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public interface Predicate<T> {
        public boolean test(T t);
    }
    Supplier<T> qui permet de fournir une valeur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 chevronné
    Avatar de la.lune
    Homme Profil pro
    Directeur Technique
    Inscrit en
    Décembre 2010
    Messages
    545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Comores

    Informations professionnelles :
    Activité : Directeur Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2010
    Messages : 545
    Points : 2 084
    Points
    2 084
    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 éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    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 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 320
    Points : 3 740
    Points
    3 740
    Billets dans le blog
    12
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  18. #38
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    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 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 320
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 320
    Points : 3 740
    Points
    3 740
    Billets dans le blog
    12
    Par défaut
    Merci beaucoup adiGuba
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

Discussions similaires

  1. JavaOne 2012 : Oracle présente la spécification JSR 353
    Par Hinault Romaric dans le forum Général Java
    Réponses: 2
    Dernier message: 13/10/2012, 10h53
  2. JavaOne 2012 : Oracle sort la Preview de NetBeans 7.3
    Par Hinault Romaric dans le forum NetBeans
    Réponses: 0
    Dernier message: 03/10/2012, 13h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo