Types library convert any object type into required object type, also can iterate hover any java object.
String str = "1234";
int number = Types.INTEGER.parse(str);
for (int i : IterableType.<Integer>ofAny(number)) {
// do something
}
double[] array = new double[] { 10.3, 8.4, 5.0 };
List<Float> list = ValueType.of(array).asList(Types.FLOAT);
for (double d : IterableType.of(array)) {
// do something
}
Map<String, String> from = Map.of("1234", "true", "55", "false", "10", "true");
Map<Integer, Boolean> to = new TypeOf<Map<Integer, Boolean>>(){}.parse(from);
for (Map.Entry<Integer, Boolean> entry : IterableType.of(to)) {
// do something
}
How to implement Types library in your project.
build.gradle
plugins {
id 'com.gradleup.shadow' version '8.3.4'
}
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'com.saicone:types:1.2'
}
jar.dependsOn (shadowJar)
shadowJar {
// Relocate types
relocate 'com.saicone.types', project.group + '.libs.types'
// Exclude unused classes (optional)
minimize()
}
build.gradle.kts
plugins {
id("com.gradleup.shadow") version "8.3.4"
}
repositories {
maven("https://jitpack.io")
}
dependencies {
implementation("com.saicone:types:1.2")
}
tasks {
jar {
dependsOn(tasks.shadowJar)
}
shadowJar {
// Relocate types
relocate("com.saicone.types", "${project.group}.libs.types")
// Exclude unused classes (optional)
minimize()
}
}
pom.xml
<repositories>
<repository>
<id>Jitpack</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.saicone</groupId>
<artifactId>types</artifactId>
<version>1.2</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<relocations>
<!-- Relocate types -->
<relocation>
<pattern>com.saicone.types</pattern>
<shadedPattern>${project.groupId}.libs.types</shadedPattern>
</relocation>
</relocations>
<!-- Exclude unused classes (optional) -->
<minimizeJar>true</minimizeJar>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</build>
A "supported" type (for example) doesn't mean you can magically convert a Map<String, Integer>
into Boolean
,
every object type that you want to parse must have a minimum sense with the conversion or null
will be return,
for example a "1.4"
can be converted into any Number
type.
Note
Any supported (primitive) object type can be returned as array value of its type.
Since primitive types cannot be explicitly null
, they will be returned with a fallback value.
Click to show
char
or'\0'
boolean
orBoolean.FALSE
byte
orByte.MIN_VALUE
short
orShort.MIN_VALUE
int
orInteger.MIN_VALUE
float
orFloat.MIN_VALUE
long
orLong.MIN_VALUE
double
orDouble.MIN_VALUE
Well known Java objects and the accepted types to properly parse them.
Click to show
java.lang.Object
java.lang.String
java.lang.Character
java.lang.Boolean
java.lang.Number
java.lang.Byte
java.lang.Short
java.lang.integer
java.lang.Float
java.lang.Long
java.lang.Double
java.math.BigInteger
java.math.BigDecimal
java.lang.Class<?>
- Qualified name, for example
some.package.for.MyClass
- File path, for example
some/package/for/MyClass.class
- Descriptor, for example
Lsome/package/for/MyClass;
- Qualified name, for example
java.util.UUID
- 36-length
String
(with dashes)00000000-0000-0000-0000-000000000000
- 32-length
String
(without dashes)00000000000000000000000000000000
- 4-length array (converted to int)
[000000000, 000000000, 000000000, 000000000]
- 2-length array (converted to long)
[mostSigBits, leastSigBits]
- 36-length
java.net.URI
String
URL
File
Path
java.net.URL
String
URI
File
Path
java.io.File
String
separated by/
String[]
java.nio.file.Path
String
separated by/
String[]
java.time.LocalDate
- Epoch day
Long
- 2-length array (converted to int)
[year, dayOfYear]
- 3-length array (converted to int)
[year, month, day]
- ISO-8601
String
- Epoch day
java.time.LocalTime
- Seconds of day
Long
- 2-length array (converted to int)
[hour, minute]
- 3-length array (converted to int)
[hour, minute, second]
- 4-length array (converted to int)
[hour, minute, second, nanoOfSecond]
String
formatted ashour:minute:second.nanoOfSecond
, examples:"10:30"
,"10:40:05"
,"09:08:21.35"
- Seconds of day
java.time.LocalDateTime
- Epoch seconds
Long
- 5-length array (converted to int)
[year, month, day, hour, minute]
- 6-length array (converted to int)
[year, month, day, hour, minute, second]
- 7-length array (converted to int)
[year, month, day, hour, minute, second, nanoOfSecond]
- ISO-8601
String
separated byT
with time formatted ashour:minute:second.nanoOfSecond
- Epoch seconds
Note
Any Number type can be parsed from:
- Boolean
true = 1 | false = 0
- Decimal, for example
35
- Binary
0[bB][0-1]
, for example0b11010
- Hex
0[xX][0-9A-Fa-f]
, for example0x46
- Hex color
#[0-9A-Fa-f]
, for example#46
- Octal
0[0-7]
, for example075
And also detect:
- Leading sings
+ -
- Unsigned suffix
u
- Number suffixes
b B s S i I f F l L d D
Typical Java objects with parameters.
Click to show
java.lang.Enum<?>
- Name
String
(case-insensitive) - Ordinal
Number
- Name
java.util.Collection<E>
- Can be any Java object that implementsCollection
java.util.Map<K, V>
- Can be any Java object that implementsMap
(The type parameters E
, K
and V
can be any supported type)
Functional Java objects to handle any type parser in a flexible way.
Click to show
java.util.Optional<E>
- Contains parsed value, empty optional type is return when parse fails or throw exceptionjava.util.concurrent.CompletableFuture<E>
- Maintain parse function into non-null return value (may throw NullPointerException)
(The type parameter E
can be any supported type)
How to use Types library.
By default, Types library can convert 6 data types using 4 different methods.
- TypeParser - Make your own implementation of type conversion.
- Types - Same as TypeParser, but every parser is cached.
- ValueType - Encapsulated object with methods to convert with Types or create one-time use TypeParser.
- TypeOf - Same as Types, but computes automatically the required type object parser (including generic objects).
Single objects:
String str = "1234";
// Using TypeParser
TypeParser<Double> parser = (object) -> Double.parseDouble(String.valueOf(object));
double number = parser.parse(str);
// Using Types (Same as TypeParser, but extract first element of any iterable or array object)
int number = Types.INTEGER.parse(str);
// Using ValueType
float number = ValueType.of(str).asFloat();
// Using TypeOf
TypeOf<Long> type = new TypeOf<Long>(){};
long number = type.parse(str);
Collections:
int number = 1234;
// Using TypeParser
TypeParser<List<Integer>> parser = TypeParser.collection(Types.INTEGER, ArrayList::new);
List<Integer> list = parser.parse(number);
// Using Types
List<Double> list = Types.DOUBLE.list(number);
// Using ValueType
List<Float> list = ValueType.of(number).asList(Types.FLOAT);
// Using TypeOf
TypeOf<List<Long>> type = new TypeOf<List<Long>>(){};
List<Long> list = type.parse(number);
Object Arrays:
String str = "1234";
// Using TypeParser
TypeParser<String> parser = TypeParser.of(String.class, String::valueOf);
String[] array = parser.array(str);
// Using Types
Integer[] array = Types.INTEGER.array(str);
// Using ValueType
String[] array = ValueType.of(str).asList(Types.STRING);
// Using TypeOf
TypeOf<Integer[]> type = new TypeOf<Integer[]>(){};
Integer[] array = type.parse(str);
Primitive Arrays:
String str = "1234";
// Using TypeParser
TypeParser<Integer> parser = TypeParser.of(int.class, object -> Integer.parseInt(String.valueOf(object)));
int[] array = parser.array(str);
// Using Types
float[] array = Types.of(float.class).array(str);
// Using ValueType
double[] array = ValueType.of(str).asArray(Types.of(double.class));
// Using TypeOf
TypeOf<long[]> type = new TypeOf<long[]>(){};
long[] array = type.parse(str);
Enums:
String str = "VALUE_NAME";
// Using TypeParser
TypeParser<MyEnum> parser = TypeParser.enumeration(MyEnum.class);
MyEnum value = parser.parse(str);
// Using ValueType
MyEnum value = ValueType.of(str).asEnum(MyEnum.class);
// Using TypeOf
TypeOf<MyEnum> type = new TypeOf<MyEnum>(){};
MyEnum value = type.parse(str);
Maps:
Map<String, String> map = new HashMap<>();
map.put("1234", "true");
map.put("55", "false");
map.put("12", "true")
// Using TypeParser
TypeParser<Map<Integer, Boolean>> parser = TypeParser.map(Types.INTEGER, Types.BOOLEAN, HashMap::new);
Map<Integer, Boolean> value = parser.parse(map);
// Using ValueType
Map<Integer, Boolean> value = ValueType.of(map).asMap(Types.INTEGER, Types.BOOLEAN, new HashMap<>());
// Using TypeOf
TypeOf<Map<Integer, Boolean>> type = new TypeOf<Map<Integer, Boolean>>(){};
Map<Integer, Boolean> value = type.parse(map);
Tip
If you create a TypeParser
or use TypeOf
is suggested to save as static final
field.
How to iterate any object value.
// Single object
String value = "text";
for (String str : IterableType.<String>ofAny(value)) {
// do something
}
// Array / Collection
Integer[] value = new Integer[] { 1, 2, 3, 4 };
int[] value = new int[] { 1, 2, 3, 4 };
List<Integer> value = new ArrayList<>();
for (int i : IterableType.of(value)) {
// do something
}
// Map
Map<String, Integer> value = new HashMap<>();
for (Map.Entry<String, Integer> entry : IterableType.of(value)) {
// do something
}
How to register your own types.
// Register
TypeParser<MyObject> parser = (object) -> {
// Convert into MyObject...
};
Types.put(MyObject.class, parser);
// Unregister
Types.remove(MyObject.class);
// Get
TypeParser<MyObject> parser = Types.of(MyObject.class);