All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.speedment.runtime.field.collector.FieldCollectors Maven / Gradle / Ivy

Go to download

A Speedment bundle that shades all dependencies into one jar. This is useful when deploying an application on a server.

The newest version!
/*
 *
 * Copyright (c) 2006-2019, Speedment, Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); You may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.speedment.runtime.field.collector;

import com.speedment.runtime.field.BooleanField;
import com.speedment.runtime.field.ByteField;
import com.speedment.runtime.field.CharField;
import com.speedment.runtime.field.DoubleField;
import com.speedment.runtime.field.Field;
import com.speedment.runtime.field.FloatField;
import com.speedment.runtime.field.IntField;
import com.speedment.runtime.field.LongField;
import com.speedment.runtime.field.ReferenceField;
import com.speedment.runtime.field.ShortField;
import com.speedment.runtime.field.StringField;
import com.speedment.runtime.field.internal.collector.FieldCollectorImpl;
import static java.util.Collections.emptySet;
import static java.util.Collections.unmodifiableSet;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
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;
import static java.util.stream.Collectors.toList;

/**
 * A number of collectors specialized for entities. These are inspired by the
 * {@link java.util.stream.Collectors} class in the java standard libraries.
 * 
 * @author Emil Forslund
 * @since  3.0.2
 */
public final class FieldCollectors {
    
    public static  Collector>>
    groupingBy(LongField field) {
        return groupingBy(field, field.getter()::apply, HashMap::new, toList());
    }
    
    public static  Collector>>
    groupingBy(IntField field) {
        return groupingBy(field, field.getter()::apply, HashMap::new, toList());
    }
    
    public static  Collector>>
    groupingBy(ShortField field) {
        return groupingBy(field, field.getter()::apply, HashMap::new, toList());
    }
    
    public static  Collector>>
    groupingBy(ByteField field) {
        return groupingBy(field, field.getter()::apply, HashMap::new, toList());
    }
    
    public static  Collector>>
    groupingBy(DoubleField field) {
        return groupingBy(field, field.getter()::apply, HashMap::new, toList());
    }
    
    public static  Collector>>
    groupingBy(FloatField field) {
        return groupingBy(field, field.getter()::apply, HashMap::new, toList());
    }
    
    public static  Collector>>
    groupingBy(BooleanField field) {
        return groupingBy(field, field.getter()::apply, HashMap::new, toList());
    }

    public static  Collector>>
    groupingBy(CharField field) {
        return groupingBy(field, field.getter()::apply, HashMap::new, toList());
    }
    
    public static  Collector>>
    groupingBy(StringField field) {
        return groupingBy(field, field.getter()::apply, HashMap::new, toList());
    }
    
    public static  Collector>>
    groupingBy(ReferenceField field) {
        return groupingBy(field, field.getter()::apply, HashMap::new, toList());
    }
    
    public static  Collector>
    groupingBy(LongField field, Collector downstream) {
        return groupingBy(field, field.getter()::apply, HashMap::new, downstream);
    }
    
    public static  Collector>
    groupingBy(IntField field, Collector downstream) {
        return groupingBy(field, field.getter()::apply, HashMap::new, downstream);
    }
    
    public static  Collector>
    groupingBy(ShortField field, Collector downstream) {
        return groupingBy(field, field.getter()::apply, HashMap::new, downstream);
    }
    
    public static  Collector>
    groupingBy(ByteField field, Collector downstream) {
        return groupingBy(field, field.getter()::apply, HashMap::new, downstream);
    }
    
    public static  Collector>
    groupingBy(DoubleField field, Collector downstream) {
        return groupingBy(field, field.getter()::apply, HashMap::new, downstream);
    }
    
    public static  Collector>
    groupingBy(FloatField field, Collector downstream) {
        return groupingBy(field, field.getter()::apply, HashMap::new, downstream);
    }
    
    public static  Collector>
    groupingBy(BooleanField field, Collector downstream) {
        return groupingBy(field, field.getter()::apply, HashMap::new, downstream);
    }
    
    public static  Collector>
    groupingBy(CharField field, Collector downstream) {
        return groupingBy(field, field.getter()::apply, HashMap::new, downstream);
    }
    
    public static  Collector>
    groupingBy(StringField field, Collector downstream) {
        return groupingBy(field, field.getter()::apply, HashMap::new, downstream);
    }
    
    public static  Collector>
    groupingBy(ReferenceField field, Collector downstream) {
        return groupingBy(field, field.getter()::apply, HashMap::new, downstream);
    }
    
    public static >
    FieldCollector groupingBy(
            Field field,
            Function classifier,
            Supplier mapFactory,
            Collector downstream) {

        Supplier downstreamSupplier = downstream.supplier();
        BiConsumer downstreamAccumulator = downstream.accumulator();
        BiConsumer, T> accumulator = (m, t) -> {
            K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");
            A container = m.computeIfAbsent(key, k -> downstreamSupplier.get());
            downstreamAccumulator.accept(container, t);
        };
        BinaryOperator> merger = FieldCollectors.>mapMerger(downstream.combiner());
        @SuppressWarnings("unchecked")
        Supplier> mangledFactory = (Supplier>) mapFactory;

        if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
            return new FieldCollectorImpl<>(field, mangledFactory, accumulator, merger, CH_ID);
        }
        else {
            @SuppressWarnings("unchecked")
            Function downstreamFinisher = (Function) downstream.finisher();
            Function, M> finisher = intermediate -> {
                intermediate.replaceAll((k, v) -> downstreamFinisher.apply(v));
                @SuppressWarnings("unchecked")
                M castResult = (M) intermediate;
                return castResult;
            };
            return new FieldCollectorImpl<>(field, mangledFactory, accumulator, merger, finisher, CH_NOID);
        }
    }

    private static >
    BinaryOperator mapMerger(BinaryOperator mergeFunction) {
        return (m1, m2) -> {
            for (Map.Entry e : m2.entrySet()) {
                m1.merge(e.getKey(), e.getValue(), mergeFunction);
            }
            return m1;
        };
    }
    
    private FieldCollectors() {}
    
    private static final Set CH_ID = 
        unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH));
    
    private static final Set CH_NOID = emptySet();
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy