msi.gama.util.GamaListFactory.java Source code

Java tutorial

Introduction

Here is the source code for msi.gama.util.GamaListFactory.java

Source

/*******************************************************************************************************
 *
 * msi.gama.util.GamaListFactory.java, in plugin msi.gama.core,
 * is part of the source code of the GAMA modeling and simulation platform (v. 1.8)
 * 
 * (c) 2007-2018 UMI 209 UMMISCO IRD/SU & Partners
 *
 * Visit https://github.com/gama-platform/gama for license information and contacts.
 * 
 ********************************************************************************************************/
package msi.gama.util;

import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import org.apache.commons.lang.ArrayUtils;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;

import msi.gama.runtime.IScope;
import msi.gama.runtime.concurrent.GamaExecutorService;
import msi.gaml.expressions.IExpression;
import msi.gaml.types.GamaType;
import msi.gaml.types.IType;
import msi.gaml.types.Types;

/**
 * Class GamaListFactory. The factory for creating lists from various other objects. All the methods that accept the
 * scope as a parameter will observe the contract of GAML containers, which is that the objects contained in the list
 * will be casted to the content type of the list. To avoid unecessary castings, some methods (without the scope
 * parameter) will simply copy the objects.
 *
 * @author drogoul
 * @since 30 janv. 2015
 *
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
public class GamaListFactory {

    private static final int DEFAULT_SIZE = 4;
    static Set<Collector.Characteristics> CH = ImmutableSet.<Collector.Characteristics>of(
            Collector.Characteristics.IDENTITY_FINISH);

    public static <T> Collector<T, IList<T>, IList<T>> toGamaList() {
        return new Collector<T, IList<T>, IList<T>>() {

            @Override
            public Supplier<IList<T>> supplier() {
                return GamaListFactory::create;
            }

            @Override
            public BiConsumer<IList<T>, T> accumulator() {
                return (left, right) -> left.add(right);
            }

            @Override
            public BinaryOperator<IList<T>> combiner() {
                return (left, right) -> {
                    left.addAll(right);
                    return left;
                };
            }

            @Override
            public java.util.function.Function<IList<T>, IList<T>> finisher() {
                return (left) -> left;
            }

            @Override
            public Set<java.util.stream.Collector.Characteristics> characteristics() {
                return CH;
            }
        };
    }

    public static Collector<Object, IList<Object>, IList<Object>> TO_GAMA_LIST = toGamaList();

    public static class GamaListSupplier implements Supplier<IList> {

        final IType t;

        public GamaListSupplier(final IType t) {
            this.t = t;
        }

        @Override
        public IList get() {
            return create(t);
        }

    }

    /**
     * Create a GamaList from an array of objects, but does not attempt casting its values.
     *
     * @param contentType
     * @param collection
     * @warning ***WARNING*** This operation can end up putting values of the wrong type into the list
     * @return
     */

    // public static <T> IList<T> create(final IType t, final Stream<T> stream)
    // {
    // return (IList<T>) createWithoutCasting(t, stream.toArray());
    // }

    public static <T> IList<T> create(final IType t, final Stream<T> stream) {
        return (IList<T>) stream.collect(TO_GAMA_LIST);
    }

    public static <T> IList<T> createWithoutCasting(final IType contentType, final T... objects) {
        final IList<T> list = create(contentType, objects.length);
        list.addAll(Arrays.asList(objects));
        return list;
    }

    public static IList<Integer> createWithoutCasting(final IType contentType, final int[] objects) {
        final IList<Integer> list = create(contentType, objects.length);
        list.addAll(Arrays.asList(ArrayUtils.toObject(objects)));
        return list;
    }

    public static IList<Double> createWithoutCasting(final IType contentType, final double[] objects) {
        final IList<Double> list = create(contentType, objects.length);
        list.addAll(Arrays.asList(ArrayUtils.toObject(objects)));
        return list;
    }

    /**
     * Create a GamaList from an iterable, but does not attempt casting its values.
     *
     * @param contentType
     * @param collection
     * @warning ***WARNING*** This operation can end up putting values of the wrong type into the list
     * @return
     */

    public static <T> IList<T> createWithoutCasting(final IType contentType, final Iterable<T> objects) {
        final IList<T> list = create(contentType);
        Iterables.addAll(list, objects);
        return list;
    }

    private static void castAndAdd(final IScope scope, final IList list, final Object o) {
        list.addValue(scope, o);
    }

    public static IList create(final IScope scope, final IType contentType, final IContainer container) {
        if (container == null) {
            return create(contentType);
        }
        if (GamaType.requiresCasting(contentType, container.getGamlType().getContentType())) {
            return create(scope, contentType, container.iterable(scope));
        } else {
            return createWithoutCasting(contentType, container.iterable(scope));
        }
    }

    public static <T> IList<T> create(final IScope scope, final IType contentType, final IList<T> container) {
        if (container == null) {
            return create(contentType);
        }
        if (GamaType.requiresCasting(contentType, container.getGamlType().getContentType())) {
            return create(scope, contentType, (Collection) container);
        } else {
            return createWithoutCasting(contentType, container);
        }
    }

    public static <T> IList<T> create(final IScope scope, final IType contentType, final Iterable<T> iterable) {
        final IList<T> list = create(contentType);
        for (final Object o : iterable) {
            castAndAdd(scope, list, o);
        }
        return list;
    }

    public static <T> IList<T> create(final IScope scope, final IType contentType, final Iterator<T> iterator) {
        final IList<T> list = create(contentType);
        if (iterator != null) {
            while (iterator.hasNext()) {
                castAndAdd(scope, list, iterator.next());
            }
        }
        return list;
    }

    public static <T> IList<T> create(final IScope scope, final IType contentType, final Enumeration<T> iterator) {
        final IList<T> list = create(contentType);
        if (iterator != null) {
            while (iterator.hasMoreElements()) {
                castAndAdd(scope, list, iterator.nextElement());
            }
        }
        return list;
    }

    @SafeVarargs
    public static <T> IList<T> create(final IScope scope, final IType contentType, final T... objects) {
        final IList<T> list = create(contentType, objects == null ? 0 : objects.length);
        if (objects != null) {
            for (final Object o : objects) {
                castAndAdd(scope, list, o);
            }
        }
        return list;
    }

    public static IList create(final IScope scope, final IType contentType, final byte[] ints) {
        final IList list = create(contentType, ints == null ? 0 : ints.length);
        if (ints != null) {
            for (final int o : ints) {
                castAndAdd(scope, list, Integer.valueOf(o));
            }
        }
        return list;
    }

    public static IList create(final IScope scope, final IType contentType, final int[] ints) {
        final IList list = create(contentType, ints == null ? 0 : ints.length);
        if (ints != null) {
            for (final int o : ints) {
                castAndAdd(scope, list, Integer.valueOf(o));
            }
        }
        return list;
    }

    public static IList create(final IScope scope, final IType contentType, final long[] ints) {
        final IList list = create(contentType, ints == null ? 0 : ints.length);
        if (ints != null) {
            for (final long o : ints) {
                castAndAdd(scope, list, Long.valueOf(o).intValue());
            }
        }
        return list;
    }

    public static IList create(final IScope scope, final IType contentType, final float[] doubles) {
        final IList list = create(contentType, doubles == null ? 0 : doubles.length);
        if (doubles != null) {
            for (final float o : doubles) {
                castAndAdd(scope, list, Double.valueOf(o));
            }
        }
        return list;
    }

    public static IList create(final IScope scope, final IExpression fillExpr, final Integer size) {
        if (fillExpr == null) {
            return create(Types.NO_TYPE, size);
        }
        final Object[] contents = new Object[size];
        final IType contentType = fillExpr.getGamlType();
        // 10/01/14. Cannot use Arrays.fill() everywhere: see Issue 778.
        if (fillExpr.isConst()) {
            final Object o = fillExpr.value(scope);
            GamaExecutorService.executeThreaded(() -> IntStream.range(0, contents.length).parallel().forEach(i -> {
                contents[i] = o;
            }));
        } else {
            GamaExecutorService.executeThreaded(() -> IntStream.range(0, contents.length).parallel().forEach(i -> {
                contents[i] = fillExpr.value(scope);
            }));
        }
        return create(scope, contentType, contents);
    }

    public static IList create(final IScope scope, final IType contentType, final double[] doubles) {
        final IList list = create(contentType, doubles == null ? 0 : doubles.length);
        if (doubles != null) {
            for (final double o : doubles) {
                castAndAdd(scope, list, Double.valueOf(o));
            }
        }
        return list;
    }

    public static <T> IList<T> create(final IType contentType, final int size) {
        return new GamaList<>(size, contentType);
    }

    public static <T> IList<T> create(final IType contentType) {
        return create(contentType, DEFAULT_SIZE);
    }

    public static <T> IList<T> create(final Class<T> clazz) {
        return create(Types.get(clazz));
    }

    public static IList create() {
        return create(Types.NO_TYPE);
    }

}