All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.namics.oss.java.tools.utils.maps.MapCreator Maven / Gradle / Ivy

There is a newer version: 2.1.0
Show newest version
/*
 * Copyright 2000-2016 Namics AG. All rights reserved.
 */

package com.namics.oss.java.tools.utils.maps;

import org.apache.maven.artifact.versioning.DefaultArtifactVersion;

import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toMap;

/**
 * This is an experimental util that provides quite fancy map initialization.
 * 

* CAUTION: performance of this method is not sufficient for high repetitive operations. *

*

* Wouldn't it be great if we could create Java maps like this? *

*
 * Map map = mapOf(
 *      one -> 1,
 *      two -> 2
 * );
 * 
*

* Here you are! *

*

* The following conditions are required for this function to work properly: *

    *
  • Java 1.8.0_80+
  • *
  • Compiled with -parameter flag
  • *
*

*

* Credits to Per-Åke Minborg. *

* * @param map entry value type * @see Creating Maps With Named Lambdas */ @FunctionalInterface public interface MapCreator extends Function, Serializable { String JAVA_VERSION = Runtime.class.getPackage().getImplementationVersion(); String MIN_JAVA_VERSION = "1.8.0_80"; default String key() { return functionalMethod().getParameters()[0].getName(); } default VALUE value() { return apply(key()); } default Method functionalMethod() { final SerializedLambda serialzedLabmda = serializedLambda(); final Class implementationClass = implementationClass(serialzedLabmda); return Stream.of(implementationClass.getDeclaredMethods()) .filter(m -> Objects.equals(m.getName(), serialzedLabmda.getImplMethodName())) .findFirst() .orElseThrow(RuntimeException::new); } default Class implementationClass(SerializedLambda serializedLambda) { try { final String className = serializedLambda.getImplClass().replaceAll("/", "."); return Class.forName(className); } catch (Exception e) { throw new RuntimeException(e); } } default SerializedLambda serializedLambda() { try { final Method replaceMethod = getClass().getDeclaredMethod("writeReplace"); replaceMethod.setAccessible(true); return (SerializedLambda) replaceMethod.invoke(this); } catch (Exception e) { throw new RuntimeException(e); } } /** * CAUTION: performance of this method is not sufficient for high repetitive operations. *

* Wouldn't it be great if we could create Java maps like this? *

*
	 * Map map = mapOf(
	 *      one -> 1,
	 *      two -> 2
	 * );
	 * 
*

* Here you are! *

*

* The following conditions are required for this function to work properly: *

    *
  • Java 1.8.0_80+
  • *
  • Compiled with -parameter flag
  • *
*

* * @param mappings lambda expressions that express map creation. * @param value type of map entry * @return initialized map. */ @SafeVarargs static Map mapOf(MapCreator... mappings) { try { return Stream.of(mappings).collect(toMap(MapCreator::key, MapCreator::value)); } catch (RuntimeException e) { checkVersion(e); throw e; } } static void checkVersion(RuntimeException e) throws UnsupportedOperationException { DefaultArtifactVersion minVersion = new DefaultArtifactVersion(MIN_JAVA_VERSION); DefaultArtifactVersion version = new DefaultArtifactVersion(JAVA_VERSION); if (version.compareTo(minVersion) < 0) { throw new UnsupportedOperationException("Java Version " + JAVA_VERSION + " is not compatible use at least " + MIN_JAVA_VERSION, e); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy