Last active
February 17, 2018 22:46
-
-
Save manoelcampos/6ab623667f835ff1296f10a0834d1212 to your computer and use it in GitHub Desktop.
A functional, generic class to show how to get String values from an array and return such values converted to the generic type.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Arrays; | |
import java.util.Objects; | |
import java.util.stream.Collectors; | |
import java.util.function.Function; | |
import java.lang.reflect.Array; | |
public class Option2<T>{ | |
private int length; | |
private String defaultValue; | |
private final Function<String, T> conversionFunction; | |
private final Class<T> klass; | |
/** | |
* Creates an Option2 that consider the values are String and don't need to be converted. | |
* If the generic type is different from String, you must use the | |
* overloaded constructor to provide a conversion {@link Function}. | |
* | |
* <p>Using this construtor for a generic type different from String | |
* will throw a RuntimeException when trying to convert the values | |
* from the Option2.</p> | |
*/ | |
@SuppressWarnings("unchecked") | |
public Option2(final Class<T> klass){ | |
this(klass, value -> (T)value); | |
} | |
public Option2(final Class<T> klass, final Function<String, T> conversionFunction){ | |
Objects.requireNonNull(conversionFunction); | |
this.conversionFunction = conversionFunction; | |
this.klass = klass; | |
} | |
public T getFirstValue(final String[] values){ | |
return getValues(values)[0]; | |
} | |
/** | |
* Gets the values of the Option2, excluding the Option2 name (the 0th element). | |
* @return an array containing the values (without the 0th element), if the values' length isn't as expected; | |
* or an array containing the default value if the length isn't as expected and there is a default value. | |
* @throws IllegalStateException when the length of values isn't as expected and there isn't a default value | |
*/ | |
public T[] getValues(final String[] values){ | |
if(defaultValue == null && values.length != length){ | |
throw new IllegalStateException("Wrong Option2 line passed, string options do only have 2 values"); | |
} | |
if(values.length == length) { | |
return createGenericArray(values, 1); | |
} | |
return createGenericArray(new String[]{defaultValue}); | |
} | |
private T[] createGenericArray(final String[] values){ | |
return createGenericArray(values, 0); | |
} | |
@SuppressWarnings("unchecked") | |
private T[] createGenericArray(final String[] values, final int startInclusive){ | |
final T[] array = (T[])Array.newInstance(klass, values.length-startInclusive); | |
//It was required to convert to list then to array in order to get an array of the generic type. | |
Arrays | |
.stream(values, startInclusive, values.length) | |
.map(this.conversionFunction) | |
.collect(Collectors.toList()) | |
.toArray(array); | |
return array; | |
} | |
/* Trying the implementation. */ | |
public static void main(String[] args) { | |
System.out.println(); | |
//Creates an Option2 of String values, which doesn't require a conversion Function. | |
Option2<String> strOpt = new Option2<>(String.class); | |
strOpt.length = 3; | |
String[] values = new String[]{"-o", "1", "2"}; | |
System.out.println("First String Value: " + strOpt.getFirstValue(values)); | |
System.out.println("String Values: " + Arrays.toString(strOpt.getValues(values))); | |
try{ | |
values = new String[]{"-o", "1"}; | |
//Error because the length of values isn't equal to 3 | |
System.out.println("First String Value: " + strOpt.getFirstValue(values)); | |
} catch(Exception e){ | |
System.out.println("\nError: " + e.getMessage() + "\n"); | |
} | |
strOpt.length = 2; | |
strOpt.defaultValue = "default value"; | |
values = new String[]{"-o"}; | |
System.out.println("First String Value: " + strOpt.getFirstValue(values)); | |
System.out.println("String Values: " + Arrays.toString(strOpt.getValues(values)) + "\n"); | |
//Creates an Option2 of Integer values, providing a Function to convert String to Integer. | |
Option2<Integer> intOpt = new Option2<>(Integer.class, value -> Integer.valueOf(value)); | |
intOpt.length = 3; | |
values = new String[]{"-o", "1", "2"}; | |
System.out.println("\nFirst Int Value: " + intOpt.getFirstValue(values)); | |
Integer[] intValues = intOpt.getValues(values); | |
System.out.println("Int Values: "); | |
for(Integer i: intValues){ | |
System.out.println(i); | |
} | |
System.out.println(); | |
values = new String[]{"-o", "99", "this value isn't a number and will throw an exception"}; | |
try { | |
System.out.println("First Int Value: " + intOpt.getFirstValue(values)); | |
intValues = intOpt.getValues(values); | |
System.out.println("Int Values: "); | |
for(Integer i: intValues){ | |
System.out.println(i); | |
} | |
}catch(RuntimeException e){ | |
System.out.println(e.getMessage()); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment