IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

Un bon développeur est un développeur flemmard !

[Java8][Stream] Comment créer une matrice mélangé !

Noter ce billet
par , 02/07/2015 à 16h07 (1336 Affichages)
Bonjour,

@mathieupicard Voulant créer une matrice "random" sans doublon, à poser la question de comment faire la comparaison 1/n. Très probablement pour vérifer que sa valeur n'est pas déjà introduit dans sa matrice.

Voulant proposer une approche différente, je me suis trouver du côté de la fonction Collections.shuffle. L'idée étant d'avoir une liste/matrice sans doublon "ordonnée" et de n'avoir qu'à la mélanger.

Mon code de base ressemblait donc à cela :
Code java : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
		int table[] = new int[9];
		// Remplissage
		for (int i = 0; i < table.length; i++) {
			table[i]=i+1;
		}
		// Conversion int[] to List<Integer> using Java 8 API
		List<Integer> list = IntStream.of(table).boxed().collect(Collectors.toList());
 
	    Collections.shuffle(list);
	    //Conversion  List<Integer> to int[] using Java 8 API
		table = list.stream().mapToInt(i -> i).toArray();
		// Affichage du résultat
		System.out.println(Arrays.toString(table));
La création de la liste initiale n'est pas très propre. Et nos n'avons pas une matrice, mais une liste.


Du coup, en cherchant un peu sur les streams, j'ai trouvé quelques blogs parlant de "Sampling" (échantillonnage) et via la classe pour faire proposer (avec les imports qui n'étaient pas précisé et un peu de commentaire) :
Code java : 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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import static java.lang.Math.max;
import static java.util.stream.Collectors.toList;
 
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
 
public class SlidingCollector<T> implements Collector<T, List<List<T>>, List<List<T>>> {
 
    private final int size;
    private final int step;
    private final int window;
    private final Queue<T> buffer = new ArrayDeque<>();
    private int totalIn = 0;
 
    /**
     * @param size Size of a group
     */
    public SlidingCollector(int size) {
    	this(size,size);
    }
 
    /**
     * @param size Size of a group
     * @param step number of element betwin each group
     */
    public SlidingCollector(int size, int step) {
        this.size = size;
        this.step = step;
        this.window = max(size, step);
    }
 
    @Override
    public Supplier<List<List<T>>> supplier() {
        return ArrayList::new;
    }
 
    @Override
    public BiConsumer<List<List<T>>, T> accumulator() {
        return (lists, t) -> {
            buffer.offer(t);
            ++totalIn;
            if (buffer.size() == window) {
                dumpCurrent(lists);
                shiftBy(step);
            }
        };
    }
 
    @Override
    public Function<List<List<T>>, List<List<T>>> finisher() {
        return lists -> {
            if (!buffer.isEmpty()) {
                final int totalOut = estimateTotalOut();
                if (totalOut > lists.size()) {
                    dumpCurrent(lists);
                }
            }
            return lists;
        };
    }
 
    private int estimateTotalOut() {
        return max(0, (totalIn + step - size - 1) / step) + 1;
    }
 
    private void dumpCurrent(List<List<T>> lists) {
        final List<T> batch = buffer.stream().limit(size).collect(toList());
        lists.add(batch);
    }
 
    private void shiftBy(int by) {
        for (int i = 0; i < by; i++) {
            buffer.remove();
        }
    }
 
    @Override
    public BinaryOperator<List<List<T>>> combiner() {
        return (l1, l2) -> {
            throw new UnsupportedOperationException("Combining not possible");
        };
    }
 
    @Override
    public Set<Characteristics> characteristics() {
        return EnumSet.noneOf(Characteristics.class);
    }
 
}l'a
Note : Les deux billets sources sont très intéressant en eux-même. (En plus d'expliquer le comportement du code)

Notre génération de matrice "random" devient beaucoup plus simple d'écriture :
Code java : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
		List<Integer> list = IntStream.range(1, 10).boxed().collect(Collectors.toList());
		Collections.shuffle(list);
		List<List<Integer>> listofList=list.stream().collect(new SlidingCollector<Integer>(3));
		int[][] test = listofList.stream().map(i -> i.stream().mapToInt(e -> e).toArray()).toArray(size -> new int[size][]);
		System.out.println(Arrays.deepToString(test));


Au final on se retrouve avec le code suivante :
Code java : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
		// On crée uine liste de 1 à 9
		List<Integer> list = IntStream.range(1, 10).boxed().collect(Collectors.toList());
		// On mélange la liste
		Collections.shuffle(list);
		// On divise la liste en groupe de 3 (taille des lignes)
		List<List<Integer>> listofList=list.stream().collect(new SlidingCollector<Integer>(3));
		// On transforme le tout en une matrice
		int[][] test = listofList.stream().map(i -> i.stream().mapToInt(j -> j).toArray()).toArray(size -> new int[size][]);
		// i correspond à un élémént de type List<Integer>
		// j correspond à un élémént de type Integer
		System.out.println(Arrays.deepToString(test));
Note : J'ai bien galéré sur la transformation de liste de liste en matrice d'entier primitif. Mais, c'est formateur !

Le résultat final étant :
Citation Envoyé par Sortie Console
[[9, 2, 4], [7, 6, 8], [5, 1, 3]]
En espérant, que cela serve.

Cordialement,
Patrick Kolodziejczyk.

source :
http://java.dzone.com/articles/group...g-and-batching
http://www.nurkiewicz.com/2014/07/gr...ng-custom.html

Envoyer le billet « [Java8][Stream] Comment créer une matrice mélangé ! » dans le blog Viadeo Envoyer le billet « [Java8][Stream] Comment créer une matrice mélangé ! » dans le blog Twitter Envoyer le billet « [Java8][Stream] Comment créer une matrice mélangé ! » dans le blog Google Envoyer le billet « [Java8][Stream] Comment créer une matrice mélangé ! » dans le blog Facebook Envoyer le billet « [Java8][Stream] Comment créer une matrice mélangé ! » dans le blog Digg Envoyer le billet « [Java8][Stream] Comment créer une matrice mélangé ! » dans le blog Delicious Envoyer le billet « [Java8][Stream] Comment créer une matrice mélangé ! » dans le blog MySpace Envoyer le billet « [Java8][Stream] Comment créer une matrice mélangé ! » dans le blog Yahoo

Catégories
Sans catégorie

Commentaires