001package squidpony; 002 003import java.util.ArrayList; 004import java.util.Collections; 005import java.util.LinkedHashMap; 006import java.util.LinkedHashSet; 007 008/** 009 * Utility methods for more easily constructing data structures, particularly those in Java's standard library. 010 * All static methods and inner classes; meant to be imported with {@code import static squidpony.Maker.*}. 011 * Created by Tommy Ettinger on 5/19/2016. 012 */ 013public class Maker { 014 015 /** 016 * Stores any information relating to non-fatal issues, such as caught and handled Exceptions that still change the 017 * behavior of methods. Typically shouldn't be cleared while debugging, since it could be useful later on, and 018 * hopefully won't need to be written to in a release build. 019 */ 020 public static final StringBuilder issueLog = new StringBuilder(1024); 021 /** 022 * Makes a LinkedHashMap (LHM) with key and value types inferred from the types of k0 and v0, and considers all 023 * parameters key-value pairs, casting the Objects at positions 0, 2, 4... etc. to K and the objects at positions 024 * 1, 3, 5... etc. to V. If rest has an odd-number length, then it discards the last item. If any pair of items in 025 * rest cannot be cast to the correct type of K or V, then this inserts nothing for that pair and logs information 026 * on the problematic pair to the static Maker.issueLog field. 027 * @param k0 the first key; used to infer the types of other keys if generic parameters aren't specified. 028 * @param v0 the first value; used to infer the types of other values if generic parameters aren't specified. 029 * @param rest an array or vararg of keys and values in pairs; should contain alternating K, V, K, V... elements 030 * @param <K> the type of keys in the returned LinkedHashMap; if not specified, will be inferred from k0 031 * @param <V> the type of values in the returned LinkedHashMap; if not specified, will be inferred from v0 032 * @return a freshly-made LinkedHashMap with K keys and V values, using k0, v0, and the contents of rest to fill it 033 */ 034 @SuppressWarnings("unchecked") 035 public static <K, V> LinkedHashMap<K, V> makeLHM(K k0, V v0, Object... rest) 036 { 037 if(rest == null) 038 return makeLHM(k0, v0); 039 LinkedHashMap<K, V> lhm = new LinkedHashMap<>(1 + (rest.length / 2)); 040 lhm.put(k0, v0); 041 042 for (int i = 0; i < rest.length - 1; i+=2) { 043 try { 044 lhm.put((K) rest[i], (V) rest[i + 1]); 045 }catch (ClassCastException cce) { 046 issueLog.append("makeLHM call had a casting problem with pair at rest["); 047 issueLog.append(i); 048 issueLog.append("] and/or rest["); 049 issueLog.append(i + 1); 050 issueLog.append("], with contents: "); 051 issueLog.append(rest[i]); 052 issueLog.append(", "); 053 issueLog.append(rest[i+1]); 054 issueLog.append(".\n\nException messages:\n"); 055 issueLog.append(cce); 056 String msg = cce.getMessage(); 057 if (msg != null) { 058 issueLog.append('\n'); 059 issueLog.append(msg); 060 } 061 issueLog.append('\n'); 062 } 063 } 064 return lhm; 065 } 066 067 /** 068 * Makes an empty LinkedHashMap (LHM); needs key and value types to be specified in order to work. For an empty 069 * LinkedHashMap with String keys and Coord values, you could use {@code Maker.<String, Coord>makeLHM();}. Using 070 * the new keyword is probably just as easy in this case; this method is provided for completeness relative to 071 * makeLHM() with 2 or more parameters. 072 * @param <K> the type of keys in the returned LinkedHashMap; cannot be inferred and must be specified 073 * @param <V> the type of values in the returned LinkedHashMap; cannot be inferred and must be specified 074 * @return an empty LinkedHashMap with the given key and value types. 075 */ 076 public static <K, V> LinkedHashMap<K, V> makeLHM() 077 { 078 return new LinkedHashMap<>(); 079 } 080 081 /** 082 * Makes an ArrayList of T given an array or vararg of T elements. 083 * @param elements an array or vararg of T 084 * @param <T> just about any non-primitive type 085 * @return a newly-allocated ArrayList containing all of elements, in order 086 */ 087 @SafeVarargs 088 public static <T> ArrayList<T> makeList(T... elements) { 089 if(elements == null) return null; 090 ArrayList<T> list = new ArrayList<>(elements.length); 091 Collections.addAll(list, elements); 092 return list; 093 } 094 095 /** 096 * Makes a LinkedHashSet (LHS) of T given an array or vararg of T elements. Duplicate items in elements will have 097 * all but one item discarded, using the later item in elements. 098 * @param elements an array or vararg of T 099 * @param <T> just about any non-primitive type 100 * @return a newly-allocated LinkedHashSet containing all of the non-duplicate items in elements, in order 101 */ 102 @SafeVarargs 103 public static <T> LinkedHashSet<T> makeLHS(T... elements) { 104 if(elements == null) return null; 105 LinkedHashSet<T> set = new LinkedHashSet<>(elements.length); 106 Collections.addAll(set, elements); 107 return set; 108 } 109 110}