Pour ce parallel, je me demande s'il y aura effectivement création de thread a la demande ou s'il y aura une sorte de pool global à la JVM un peu comme en .Net (la classe ThreadPool qui s'utilise statiquement).
Version imprimable
Pour ce parallel, je me demande s'il y aura effectivement création de thread a la demande ou s'il y aura une sorte de pool global à la JVM un peu comme en .Net (la classe ThreadPool qui s'utilise statiquement).
A première vue il semblerait que ce soit le cas.
Les threads sont nommés "ForkJoinPool.commonPool-worker-X" ce qui semble indiquer qu'ils utilisent le framework ForkJoin de Java 7 avec un pool commun.
D'ailleurs la javadoc de ForkJoinPool et ForkJoinPool.commonPool() semble le confirmer...
a++
Bon j'ai fait mes petits essais avec le JDK8. Dommage que netbeans ne reconnaisse pas déjà les lambdas.
Sinon voilà la concision obtenu avec ma petite librairie maison React4J
On dit merci les lambdas.... :ccool:Code:
1
2
3
4
5
6
7
8 Var<String> mouseAndTime = MouseReact.button1() .map(arg1->arg1 ? "button pressed" : "button released") .toVar("no button yet !") .merge(mouseX, (arg1, arg2)->arg1 + " ( x=" + arg2) .merge(mouseY, (arg1, arg2)->arg1 + ", y=" + arg2 + ")"); label1.setText(mouseAndTime);
Il me semblais que depuis la version 6, Netbeans essayait de suivre la numérotation des versions majeures du JDK. Bizarre qu'il ne l'ait pas nommé 8.0. Le support du JDK 8.0 est il complet?
Ca vas trop vite !!!! Je ne suis jamais à jour. Terrible.
Je télécharge la bête de ce pas. :ccool: merci :ccool:
En tous cas, niveau code source ça change pas mal la donne pour utiliser ma lib. Je suis assez content. En plus comme c'est retro-compatible, ça ne m'a pas demandé beaucoup de changement.... :ccool::ccool::ccool::ccool: merci Oracle (mince je me rend compte que je ne m’imaginais jamais dire un truc pareil !!!! :aie::aie::aie::aie:)
Des slides de Devoxx : "Autumn Collections, From Iterable to Lambdas, Streams and Collectors"
http://fr.slideshare.net/jpaumard/au...and-collectors
a++
Au fait ! Pour résumer ce que dit José Paumard, les lambdas permettent une programmation déclarative plutôt qu'impérative.
Ils permettent, dans le cas des listes (mais également de évènements (FRP), IO etc.) de programmer le quoi plutôt que le comment !
Dans sa démo, sa fonction de réduction calcul la somme. Il pourrait directement calculer la moyenne à l'aide d'une suite. Mais ça sous entends d'entretenir un index.
Je viens de tomber sur ce bout de code sur la mailling-list du projet lambda.
Il consiste à rechercher toutes les méthodes par défaut des interfaces d'un fichier jar passé en paramètre (rt.jar par exemple) :
Mis à part la méthode loadClassFromFileName(), tout est fait via l'API de Stream, via JarFile qui propose un stream() sur ses entrées (JarEntry).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 public class AllDefaultMethods { private static Class<?> loadClassFromFileName(String name) { String className = name.substring(0, name.length() - ".class".length()); try { return Class.forName(className.replace('/', '.')); } catch (Throwable t) { // skip unknown class, or LinkageError return null; } } public static void main(String... args) throws IOException { try (JarFile jarFile = new JarFile(args[0])) { jarFile.stream() .map(JarEntry::getName) .filter(name -> name.endsWith(".class")) .map(AllDefaultMethods::loadClassFromFileName) .filter(Objects::nonNull) .flatMap(type -> Arrays.stream(type.getDeclaredMethods())) .filter(Method::isDefault) .forEach(System.out::println); } } }
Pour chaque JarEntry :
- map(JarEntry::getName) récupère le nom du fichier.
- filter(name -> name.endsWith(".class")) filtre seulement les fichiers *.class
- map(AllDefaultMethods::loadClassFromFileName) tente de charger la Class correspondante (ou renvoi null en cas d'erreur)
- filter(Objects::nonNull) permet donc d'ignorer les classes qui n'ont pas pu être chargée.
- flatMap(type -> Arrays.stream(type.getDeclaredMethods())) récupère les Methods de la classe.
- filter(Method::isDefault) filtre seulement les méthode par défaut.
- Et enfin forEach(System.out::println) affiche la méthode dans System.out
Il manque juste un filter(Class::isInterface) pour limiter la recherche de méthodes par défaut dans les interfaces...
Simple !
Pour info, en Java 7 un code similaire s'écrierait comme cela :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 public static void main(String... args) throws IOException { try (JarFile jarFile = new JarFile(args[0])) { Enumeration<JarEntry> entries = jarFile.entries(); while (entries.hasMoreElements()) { String name = entries.nextElement().getName(); if (name.endsWith(".class")) { Class<?> clazz = AllDefaultMethods.loadClassFromFileName(name); if (clazz!=null) { for (Method method : clazz.getDeclaredMethods()) { if (method.isDefault()) { System.out.println(method); } } } } } } }
a++
abiGuda, tu te rend compte que ton second code est plus court que le premier :aie::aie::aie::aie:
Te chari. Les lambdas c'est plus élégant !
Tien jete un oeil là dessus : http://www.developpez.net/forums/d13...s-langage-sql/
Si tu remplace :
- Select par map
- Where par filter
- (orderby, max, min, count, average) par reduce
On comprend pourquoi LINQ a été mis en place et surtout sur quoi la réflexion c'est elle basée. ;)
Non. Il est malgré tout légèrement plus court en plus d'être plus lisible ;)
C'est juste que je n'ai pas répété la méthode loadClassFromFileName() dans le second code... mais elle y est aussi utilisé ;)
Et oui le principe des Stream est similaire à celui des requêtes SQL ;)
Sinon les "checked-exceptions" seront encore plus emmerdante avec Java 8 et les lambdas, puisqu'il faut que les interfaces fonctionnelles définissent ces exceptions pour qu'elles soient utilisable.
Par exemple, si je veux récupérer les noms/emails de certains utilisateurs afin de préparer un mailing.
Pour afficher cela sur la console il n'y a aucun soucis :
Code:
1
2
3
4
5
6 List<User> users = ... users.stream() .filter(User::isOptin) .filter(u -> u.getEmail()!=null ) .map(u -> u.getName() + "\t" + u.getEmail()) .forEach(System.out::println);
Maintenant, si je veux stocker cela dans un fichier via un Writer, je ne peux pas le faire directement car l'exception ne peut pas être utilisée dans forEach puisque l'interface Consumer ne déclare pas d'exception :
Code:
1
2
3
4
5
6
7
8 List<User> users = ... try (Writer out = new FileWriter("out.txt")) { users.stream() .filter(User::isOptin) .filter(u -> u.getEmail()!=null ) .map(u -> u.getName() + "\t" + u.getEmail()) .forEach(out::append); // ERROR : incompatible throws type IOException }
Pas cool :?
a++