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.HashMap; 026import java.util.LinkedHashMap; 027import java.util.LinkedHashSet; 028import java.util.List; 029import java.util.Map; 030import java.util.Set; 031import java.util.function.Consumer; 032 033/** 034 * Provides a set of methods that produce unmodifiable copies of collections. 035 * 036 * @since 4.0.0 037 */ 038public final class UnmodifiableCollections { 039 040 private UnmodifiableCollections() {} 041 042 /** 043 * Creates an unmodifiable copy of the given {@link List} instance. 044 * 045 * @param original the list to be copied 046 * @param <E> the type of every item in the entry 047 * @return a unmodifiable copy of the given {@link List} instance 048 * 049 * @since 4.0.0 050 */ 051 public static <E> List<E> copyOf(final List<E> original) { 052 switch (original.size()) { 053 case 0: 054 return Collections.emptyList(); 055 case 1: 056 return Collections.singletonList(original.get(0)); 057 default: 058 return Collections.unmodifiableList(new ArrayList<>(original)); 059 } 060 } 061 062 /** 063 * Creates an unmodifiable copy of the given {@link Set} instance. 064 * 065 * @param original the set to be copied 066 * @param <E> the type of every item in the entry 067 * @return a unmodifiable copy of the given {@link Set} instance 068 * @since 4.0.0 069 */ 070 public static <E> Set<E> copyOf(final Set<E> original) { 071 switch (original.size()) { 072 case 0: 073 return Collections.emptySet(); 074 case 1: 075 return Collections.singleton(original.iterator().next()); 076 default: 077 return Collections.unmodifiableSet(new LinkedHashSet<>(original)); 078 } 079 } 080 081 /** 082 * Creates an unmodifiable copy of the given {@link Map} instance. 083 * 084 * @param original the map to be copied 085 * @param <K> key type of the map 086 * @param <V> value type of the map 087 * @return an unmodifiable copy of the given {@link Map} instance. 088 * @since 4.1.0 089 */ 090 public static <K, V> Map<K, V> copyOf(final Map<K, V> original) { 091 switch (original.size()) { 092 case 0: 093 return Collections.emptyMap(); 094 case 1: 095 final Map.Entry<K, V> entry = original.entrySet().iterator().next(); 096 return Collections.singletonMap(entry.getKey(), entry.getValue()); 097 default: 098 if (original instanceof LinkedHashMap<?, ?>) { 099 return Collections.unmodifiableMap(new LinkedHashMap<>(original)); 100 } else { 101 return Collections.unmodifiableMap(new HashMap<>(original)); 102 } 103 } 104 } 105 106 /** 107 * Creates an unmodifiable copy of the given array as a list, 108 * preserving order. 109 * 110 * @param original the array to be copied into a list 111 * @param <E> the type of every item in the entry 112 * @return a unmodifiable copy of the given array as a {@link List} instance 113 * @since 4.0.0 114 */ 115 @SafeVarargs 116 @SuppressWarnings("varargs") 117 public static <E> List<E> toList(final E... original) { 118 switch (original.length) { 119 case 0: 120 return Collections.emptyList(); 121 case 1: 122 return Collections.singletonList(original[0]); 123 default: 124 return Collections.unmodifiableList(new ArrayList<>(Arrays.asList(original))); 125 } 126 } 127 128 /** 129 * Creates an unmodifiable copy of the given array as a set. 130 * 131 * @param original the array to be copied into a set 132 * @param <E> the type of every item in the entry 133 * @return a unmodifiable copy of the given array as a {@link Set} instance 134 * @since 4.0.0 135 */ 136 @SafeVarargs 137 @SuppressWarnings("varargs") 138 public static <E> Set<E> toSet(final E... original) { 139 switch (original.length) { 140 case 0: 141 return Collections.emptySet(); 142 case 1: 143 return Collections.singleton(original[0]); 144 default: 145 return Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList(original))); 146 } 147 } 148 149 /** 150 * Build an unmodifiable map. 151 * 152 * @param <K> key type 153 * @param <V> value type 154 * @param handler consumer that will populate the map wih keys 155 * @return a new unmodifiable map 156 * @since 4.0.0 157 */ 158 public static <K, V> Map<K, V> buildMap(final Consumer<Map<K, V>> handler) { 159 final Map<K, V> builder = new LinkedHashMap<>(); 160 requireNonNull(handler, "handler").accept(builder); 161 return Collections.unmodifiableMap(builder); 162 } 163 164 /** 165 * Creates an immutable instance of {@link Map.Entry}. 166 * 167 * @param key the key in the entry 168 * @param value the value in the entry 169 * @param <K> the key's type 170 * @param <V> the value's type 171 * @return the new map entry 172 * @since 4.0.0 173 */ 174 public static <K, V> Map.Entry<K, V> immutableMapEntry(final K key, final V value) { 175 return new AbstractMap.SimpleImmutableEntry<>(key, value); 176 } 177 178}