001/*
002 * Configurate
003 * Copyright (C) zml and Configurate contributors
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *    http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.spongepowered.configurate.util;
018
019import static java.util.Objects.requireNonNull;
020
021import java.util.AbstractMap;
022import java.util.ArrayList;
023import java.util.Arrays;
024import java.util.Collections;
025import java.util.LinkedHashMap;
026import java.util.LinkedHashSet;
027import java.util.List;
028import java.util.Map;
029import java.util.Set;
030import java.util.function.Consumer;
031
032/**
033 * Provides a set of methods that produce unmodifiable copies of collections.
034 *
035 * @since 4.0.0
036 */
037public final class UnmodifiableCollections {
038
039    private UnmodifiableCollections() {}
040
041    /**
042     * Creates an unmodifiable copy of the given {@link List} instance.
043     *
044     * @param original the list to be copied
045     * @param <E> the type of every item in the entry
046     * @return a unmodifiable copy of the given {@link List} instance
047     *
048     * @since 4.0.0
049     */
050    public static <E> List<E> copyOf(final List<E> original) {
051        switch (original.size()) {
052            case 0:
053                return Collections.emptyList();
054            case 1:
055                return Collections.singletonList(original.get(0));
056            default:
057                return Collections.unmodifiableList(new ArrayList<>(original));
058        }
059    }
060
061    /**
062     * Creates an unmodifiable copy of the given {@link Set} instance.
063     *
064     * @param original the set to be copied
065     * @param <E> the type of every item in the entry
066     * @return a unmodifiable copy of the given {@link Set} instance
067     * @since 4.0.0
068     */
069    public static <E> Set<E> copyOf(final Set<E> original) {
070        switch (original.size()) {
071            case 0:
072                return Collections.emptySet();
073            case 1:
074                return Collections.singleton(original.iterator().next());
075            default:
076                return Collections.unmodifiableSet(new LinkedHashSet<>(original));
077        }
078    }
079
080    /**
081     * Creates an unmodifiable copy of the given array as a list, preserving
082     * order.
083     *
084     * @param original the array to be copied into a list
085     * @param <E> the type of every item in the entry
086     * @return a unmodifiable copy of the given array as a {@link List}
087     *         instance
088     * @since 4.0.0
089     */
090    @SafeVarargs
091    @SuppressWarnings("varargs")
092    public static <E> List<E> toList(final E... original) {
093        switch (original.length) {
094            case 0:
095                return Collections.emptyList();
096            case 1:
097                return Collections.singletonList(original[0]);
098            default:
099                return Collections.unmodifiableList(new ArrayList<>(Arrays.asList(original)));
100        }
101    }
102
103    /**
104     * Creates an unmodifiable copy of the given array as a set.
105     *
106     * @param original the array to be copied into a set
107     * @param <E> the type of every item in the entry
108     * @return a unmodifiable copy of the given array as a {@link Set} instance
109     * @since 4.0.0
110     */
111    @SafeVarargs
112    @SuppressWarnings("varargs")
113    public static <E> Set<E> toSet(final E... original) {
114        switch (original.length) {
115            case 0:
116                return Collections.emptySet();
117            case 1:
118                return Collections.singleton(original[0]);
119            default:
120                return Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList(original)));
121        }
122    }
123
124    /**
125     * Build an unmodifiable map.
126     *
127     * @param <K> key type
128     * @param <V> value type
129     * @param handler consumer that will populate the map wih keys
130     * @return a new unmodifiable map
131     * @since 4.0.0
132     */
133    public static <K, V> Map<K, V> buildMap(final Consumer<Map<K, V>> handler) {
134        final Map<K, V> builder = new LinkedHashMap<>();
135        requireNonNull(handler, "handler").accept(builder);
136        return Collections.unmodifiableMap(builder);
137    }
138
139    /**
140     * Creates an immutable instance of {@link Map.Entry}.
141     *
142     * @param key the key in the entry
143     * @param value the value in the entry
144     * @param <K> the key's type
145     * @param <V> the value's type
146     * @return the new map entry
147     * @since 4.0.0
148     */
149    public static <K, V> Map.Entry<K, V> immutableMapEntry(final K key, final V value) {
150        return new AbstractMap.SimpleImmutableEntry<>(key, value);
151    }
152
153}