HC's Blog


HonniCilest

Erfahrenes Mitglied
#1
Mein erster Beitrag soll nur ein kleines Codebeispiel sein. Es ist ein CustomCollector, den ich selbst schon mehrmals angewendet habe:

Java:
package tutorials.de.custom;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * A personal collection of custom Collector implementations.
 *
 * @author HonniCilest
 */
public class CustomCollectors {
 
    /**
     * Returns a random elements of the stream.
     *
     * @param <T> Type of the streamed element.
     * @return A random element of the stream.<br>
     * Returns null if the stream contained no element.
     */
    public static <T> Collector<T, ?, T> pickRandom() {
        Function<List<T>, T> finisher = list -> {
            return list.size() > 0
                    ? list.get(new Random().nextInt(list.size()))
                    : null;
        };
        
        return Collectors.collectingAndThen(Collectors.toList(), finisher);
    }
    
    /**
     * Returns a list of random elements with the given length.
     * @param <T> Type of the streamed element.
     * @param n Amount of elements to be returned.
     * @return A list of random elements of the stream with given length max.
     * @throws IllegalArgumentException If the given amount is negative.
     */
    public static <T> Collector<T, ?, List<T>> pickRandom(int n)
            throws IllegalArgumentException {
        if (n < 1) {
            throw new IllegalArgumentException("Argument must be positive.");
        }

        Function<List<T>, List<T>> finisher = list -> {
            Collections.shuffle(list);
            return list.size() <= n
                    ? list
                    : list.subList(0, n);
        };
        
        return Collectors.collectingAndThen(Collectors.toList(), finisher);
    };
    
    /**
     * Returns a randomized list of the streamed elements.
     *
     * @param <T> Type of the streamed element.
     * @return A randomized list of the streamed elements
     */
    public static <T> Collector<T, ?, List<T>> toShuffledList() {
        Function<List<T>, List<T>> finisher = list -> {
            Collections.shuffle(list);
            return list;
        };
        
        return Collectors.collectingAndThen(Collectors.toList(), finisher);
    };
    
    /**
     * Returns a randomized list of the streamed elements
     * 
     * @param <T> Type of the streamed element
     * @param left Number of elements fixed at the beginning of the list
     * @param right Number of elements fixed at the end of the list
     * @return A randomized list of the streamed elements
     */
    public static <T> Collector<T, ?, List<T>> toShuffledList(int left, int right) {
        // TODO: validate left and right
        
        Function<List<T>, List<T>> finisher = list -> {
            Collections.shuffle(list.subList(left, list.size() - right));
            return list;
        };
        
        return Collectors.collectingAndThen(Collectors.toList(), finisher);
    };
}
Anwendungsbeispiele:
Java:
// Der Apfel bei Snake muss auf einem zufälligen freien Feld platziert werden nachdem er von der Schlange gefressen wurde
FieldModel freeField = fieldList.stream().filter(field -> field.isFree()).collect(CustomCollectors.pickRandom());
if(freeField != null) freeField.placeApple();

// Lehrer wählt zufällig n Schüler aus seiner Klasse aus, aber nur aus denen welche sich gemeldet haben
List<Student> volunteers = studentList.stream().filter(student -> student.hasHandRaised()).collect(CustomCollectors.pickRandom(n));
for(Student student : volunteers) sendToTrip(student);

// Bei einem Multiple-Choice Test werden die korrekten und die falschen Fragen in einer zufälligen Reihenfolge ausgegeben
List<String> allChoices = Stream.concat(answers.stream(), dummies.stream()).collect(CustomCollectors.toShuffledList());
 
Zuletzt bearbeitet: