package de.axone.tools;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import de.axone.data.collections.DoubleImmutableSet;
import de.axone.data.collections.SingleImmutableList;
import de.axone.data.collections.SingleImmutableMap;
import de.axone.data.collections.SingleImmutableSet;
import de.axone.data.tupple.Pair;
import de.axone.exception.Assert;
public abstract class Mapper {
public static class MapperEntry<X,Y> {
private final X x;
private final Y y;
public MapperEntry( X x, Y y ) {
this.x = x; this.y = y;
}
}
public static <X,Y> MapperEntry<X,Y> E( X x, Y y ){
return new MapperEntry<X,Y>( x, y );
}
@SafeVarargs
public static <X,Y> HashMap<X,Y> hashMap( MapperEntry<X,Y> ... values ){
return map( new HashMap<X,Y>(), false, values );
}
@SafeVarargs
public static <X,Y> TreeMap<X,Y> treeMap( MapperEntry<X,Y> ... values ){
return map( new TreeMap<X,Y>(), false, values );
}
// Maps for Lists
@SafeVarargs
public static <T> HashMap<T,T> hashMap( T ... values ){
return map( new HashMap<T,T>(), false, values );
}
@SafeVarargs
public static <T> HashMap<T,T> hashMap( T [] ... values ){
return map( new HashMap<T,T>(), false, values );
}
@SafeVarargs
public static <T> TreeMap<T,T> treeMap( T ... values ){
return map( new TreeMap<T,T>(), false, values );
}
@SafeVarargs
public static <T> TreeMap<T,T> treeMap( T [] ... values ){
return map( new TreeMap<T,T>(), false, values );
}
@SafeVarargs
public static <T> LinkedHashMap<T,T> linkedHashMap( T ... values ){
return map( new LinkedHashMap<T,T>(), false, values );
}
@SafeVarargs
public static <T> HashMap<T,T> hashMapIgnoreEmptyValues( T ... values ){
return map( new HashMap<T,T>(), true, values );
}
@SafeVarargs
public static <T> TreeMap<T,T> treeMapIgnoreEmptyValues( T ... values ){
return map( new TreeMap<T,T>(), true, values );
}
@SafeVarargs
public static <T> LinkedHashMap<T,T> linkedHashMapIgnoreEmptyValues( T ... values ){
return map( new LinkedHashMap<T,T>(), true, values );
}
@SafeVarargs
public static <T,M extends Map<T,T>> M map( M result, boolean ignoreEmptyValues, T ... values ){
if( (values.length % 2) != 0 )
throw new IllegalArgumentException( "Only even argument count allowed" );
for( int i = 0; i < values.length; i+= 2 ){
if( ignoreEmptyValues || values[ i+1 ] != null )
result.put( values[ i ], values[ i+1 ] );
}
return result;
}
@SafeVarargs
public static <T,M extends Map<T,T>> M map( M result, boolean ignoreEmptyValues, T [] ... values ){
for( T [] value : values ){
if( ignoreEmptyValues || value[ 1 ] != null )
result.put( value[ 0 ], value[ 1 ] );
}
return result;
}
@SafeVarargs
public static <X,Y,M extends Map<X,Y>> M map( M result, boolean ignoreEmptyValues, MapperEntry<X,Y> ... values ){
for( MapperEntry<X,Y> e : values ){
result.put( e.x, e.y );
}
return result;
}
// Map List to Map via key extraction
public <K,O, M extends Map<K,O>> M map( M result, KeyExtractor<K,O> extractor, Iterable<O> objects ){
for( O value : objects ){
result.put( extractor.extract( value ), value );
}
return result;
}
public <K,O> HashMap<K,O> hashMap( KeyExtractor<K,O> extractor, Iterable<O> objects ){
return map( new HashMap<K,O>(), extractor, objects );
}
public <K,O> TreeMap<K,O> treeMap( KeyExtractor<K,O> extractor, Iterable<O> objects ){
return map( new TreeMap<K,O>(), extractor, objects );
}
@SuppressWarnings( "unchecked" )
public <K,O> HashMap<K,O> hashMap( KeyExtractor<K,O> extractor, O ... object ){
return map( new HashMap<K,O>(), extractor, Arrays.asList( object ) );
}
@SuppressWarnings( "unchecked" )
public <K,O> TreeMap<K,O> treeMap( KeyExtractor<K,O> extractor, O ... object ){
return map( new TreeMap<K,O>(), extractor, Arrays.asList( object ) );
}
// Maps for two Arrays
public static <K,V> HashMap<K,V> hashMap( K[] k, V[] v ){
return map( new HashMap<K,V>(), k, v );
}
public static <K,V> TreeMap<K,V> treeMap( K[] k, V[] v ){
return map( new TreeMap<K,V>(), k, v );
}
public static <K,V> LinkedHashMap<K,V> linkedHashMap( K[] k, V[] v ){
return map( new LinkedHashMap<K,V>(), k, v );
}
public static <K,V,M extends Map<K,V>> M map( M result, K[] k, V[] v ){
if( k.length != v.length )
throw new IllegalArgumentException( "Argument count missmatch: " + k.length + "/" + v.length );
for( int i = 0; i < k.length; i++ ){
result.put( k[ i ], v[ i ] );
}
return result;
}
@SafeVarargs
public static <K,V> TreeMap<K,V> treeMap( Pair<K,V> ... values ){
return map( new TreeMap<K,V>(), values );
}
@SafeVarargs
public static <K,V> HashMap<K,V> hashMap( Pair<K,V> ... values ){
return map( new HashMap<K,V>(), values );
}
@SafeVarargs
public static <K,V,M extends Map<K,V>> M map( M result, Pair<K,V> ... values ){
for( Pair<K,V> value : values ){
result.put( value.getLeft(), value.getRight() );
}
return result;
}
// Set
@SafeVarargs
public static <T> HashSet<T> hashSet( T ... values ){
HashSet<T> result = new HashSet<T>( Arrays.asList( values ));
return result;
}
@SafeVarargs
public static <T> HashSet<T> linkedHashSet( T ... values ){
HashSet<T> result = new LinkedHashSet<T>( Arrays.asList( values ));
return result;
}
@SafeVarargs
public static <T> TreeSet<T> treeSet( T ... values ){
TreeSet<T> result = new TreeSet<T>( Arrays.asList( values ));
return result;
}
// Converted Set
@SafeVarargs
public static <T,X> HashSet<T> hashSet( Converter<T,X> converter, X ... values ){
Assert.notNull( converter, "converter" );
if( values == null ) return new HashSet<T>();
HashSet<T> result = new HashSet<T>( values.length );
for( X value : values ){
result.add( converter.convert( value ) );
}
return result;
}
@SafeVarargs
public static <T,X> TreeSet<T> treeSet( Converter<T,X> converter, X ... values ){
Assert.notNull( converter, "converter" );
if( values == null ) return new TreeSet<T>();
TreeSet<T> result = new TreeSet<T>();
for( X value : values ){
result.add( converter.convert( value ) );
}
return result;
}
public static <T> List<T> list( Collection<T> values ) {
if( values instanceof List ) {
return (List<T>) values;
} else {
return new ArrayList<>( values );
}
}
@SafeVarargs
public static <T> LinkedList<T> linkedList( T ... values ){
return new LinkedList<T>( Arrays.asList( values ) );
}
@SafeVarargs
public static <T> ArrayList<T> arrayList( T ... values ){
return new ArrayList<T>( Arrays.asList( values ) );
}
public static <T> LinkedList<T> toLinkedListIfNeeded( Collection<T> values ){
if( values instanceof ArrayList ) {
return (LinkedList<T>) values;
} else {
return new LinkedList<>( values );
}
}
public static <T> ArrayList<T> toArrayListIfNeeded( Collection<T> values ){
if( values instanceof ArrayList ) {
return (ArrayList<T>) values;
} else {
return new ArrayList<>( values );
}
}
@SafeVarargs
public static <T,X> LinkedList<T> linkedList( Converter<T,X> converter, X ... values ){
return collection( new LinkedList<T>(), converter, values );
}
@SafeVarargs
public static <T,X> ArrayList<T> arrayList( Converter<T,X> converter, X ... values ){
return collection( new ArrayList<T>( values.length ), converter, values );
}
@SafeVarargs
public static <T,X,C extends Collection<T>> C collection( C result, Converter<T,X> converter, X ... values ){
fill( result, converter, values );
return result;
}
@SafeVarargs
private static <T,X> void fill( Collection<T> result, Converter<T,X> converter, X ... values ){
Assert.notNull( converter, "converter" );
for( X value : values ){
result.add( converter.convert( value ) );
}
}
public static <T,U> List<String> mapToList( String joinWith, Map<T,U> map ){
LinkedList<String> result = new LinkedList<String>();
for( Map.Entry<T,U> entry : map.entrySet() ) {
result.add( entry.getKey().toString() +
joinWith + entry.getValue().toString() );
}
return result;
}
/*
private static final class NoConverter<T> implements Converter<T,T>{
@Override
public T convert( T value ) { return value; }
}
*/
public static Map<String,String> split( String rs, String fs, String joined ){
Map<String,String> result = new TreeMap<String,String>();
String[] records = joined.split( rs );
for( String record : records ){
String[] fields = record.split( fs );
for( int i=0; i<2; i++ ) fields[i] = fields[i].trim();
result.put( fields[0], fields[1] );
}
return result;
}
public static <X,Y,M extends Map<X,Y>> M clean( M map ){
LinkedList<X> empty = new LinkedList<X>();
for( Map.Entry<X,Y> entry : map.entrySet() ){
if( entry.getValue() == null ) empty.add( entry.getKey() );
}
for( X key : empty ){
map.remove( key );
}
return map;
}
// Fast Sets
public static <T> Set<T> immutableSet( T value ){
return new SingleImmutableSet<>( value );
}
public static <T> Set<T> immutableSet( T value1, T value2 ){
return new DoubleImmutableSet<>( value1, value2 );
}
public static <T> List<T> immutableList( T value ){
return new SingleImmutableList<>( value );
}
public static <K,V> Map<K,V> immutableMap( K key, V value ){
return new SingleImmutableMap<>( key, value );
}
public interface Converter<T,X> {
public T convert( X value );
}
public interface KeyExtractor<K,O> {
public K extract( O object );
}
public static <T> Set<T> asSetOrNull( T item ) {
if( item == null ) return null;
return immutableSet( item );
}
@SuppressWarnings( "unchecked" )
public static <T> Set<T> asSet( T ... items ) {
if( items == null ) return null;
if( items.length == 0 ) return Collections.emptySet();
if( items.length == 1 ) return asSetOrNull( items[ 0 ] );
return new HashSet<>( Arrays.asList( items ) );
}
/**
* @return collection as set. either a new one or the old one if it's already a set.
*
* @param items
*/
public static <T> Set<T> asSet( Iterable<T> items ) {
if( items == null ) return null;
if( items instanceof Set ) return (Set<T>)items;
if( items instanceof Collection ) return new HashSet<>( (Collection<T>) items );
HashSet<T> result = new HashSet<>();
for( T t : items ) result.add( t );
return result;
}
/**
* @return collection as list. either a new one or the old one if it's already a list.
*
* @param items
*/
public static <T> List<T> asList( Iterable<T> items ) {
if( items == null ) return null;
if( items instanceof List ) return (List<T>)items;
if( items instanceof Collection ) return new ArrayList<>( (Collection<T>) items );
ArrayList<T> result = new ArrayList<>();
for( T t : items ) result.add( t );
return result;
}
@SuppressWarnings( "unchecked" )
public static <T> LinkedList<T> asLinkedList( T ... items ){
if( items == null ) return null;
LinkedList<T> result = new LinkedList<>();
for( T item : items ) result.add( item );
return result;
}
@SuppressWarnings( "unchecked" )
public static <T> ArrayList<T> asArrayList( T ... items ){
if( items == null ) return null;
ArrayList<T> result = new ArrayList<>();
for( T item : items ) result.add( item );
return result;
}
public static <T> T[] asArray( Class<T> clazz, Collection<T> aids ) {
@SuppressWarnings( "unchecked" )
T [] result = (T[]) Array.newInstance( clazz, aids.size() );
result = aids.toArray( result );
return result;
}
}