- Java map class to object
- Learn Latest Tutorials
- Preparation
- Trending Technologies
- B.Tech / MCA
- Javatpoint Services
- Training For College Campus
- Saved searches
- Use saved searches to filter your results more quickly
- License
- Jarcionek/Map-To-Object-Converter
- Name already in use
- Sign In Required
- Launching GitHub Desktop
- Launching GitHub Desktop
- Launching Xcode
- Launching Visual Studio Code
- Latest commit
- Git stats
- Files
- README.md
Java map class to object
Learn Latest Tutorials
Preparation
Trending Technologies
B.Tech / MCA
Javatpoint Services
JavaTpoint offers too many high quality services. Mail us on h[email protected], to get more information about given services.
- Website Designing
- Website Development
- Java Development
- PHP Development
- WordPress
- Graphic Designing
- Logo
- Digital Marketing
- On Page and Off Page SEO
- PPC
- Content Development
- Corporate Training
- Classroom and Online Training
- Data Entry
Training For College Campus
JavaTpoint offers college campus training on Core Java, Advance Java, .Net, Android, Hadoop, PHP, Web Technology and Python. Please mail your requirement at [email protected].
Duration: 1 week to 2 week
Like/Subscribe us for latest updates or newsletter
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
A tool that allows to easily convert Map returned by jdbi into staticly typed classes
License
Jarcionek/Map-To-Object-Converter
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
A tool that allows to easily convert Map returned by jdbi (but not only) into staticly typed objects.
public enum Gender < MALE, FEMALE > public class Employee < public final String name; public final int age; public final Gender gender; public final OptionalString> phoneNumber; public Employee(String name, int age, Gender gender, OptionalString> phoneNumber) < this.name = name; this.age = age; this.gender = gender; this.phoneNumber = phoneNumber; > > public class Example < @Test public void convertsMapToEmployee() < MapString, Object> employeeMap = new HashMap<>(); employeeMap.put("name", "Jaroslaw Pawlak"); employeeMap.put("age", 26); employeeMap.put("gender", "MALE"); employeeMap.put("phoneNumber", null); MapToObjectConverter converter = new MapToObjectConverter(); Employee employee = converter.convert(employeeMap, Employee.class); assertEquals("Jaroslaw Pawlak", employee.name); assertEquals(26, employee.age); assertEquals(Gender.MALE, employee.gender); assertEquals(Optional.empty(), employee.phoneNumber); // multiple assertions give poor diagnostics, use shazamcrest instead > >
Registering single value converters for non-optional fields
But what if gender in our database is integer value, where 0 means male and 1 means female? We do not want to have int field in our code, we still want to have Gender enum. In such cases we would usually add a method to our Gender class:
public enum Gender < MALE(0), FEMALE(1); private final int number; Gender(int number) < this.number = number; > public static Gender fromInt(int number) < return stream(Gender.values()) .filter(enumValue -> enumValue.number == number) .findFirst() .orElseThrow(() -> new IllegalArgumentException("No enum for number " + number)); > >
Now all we have to do is to register this method on the converter:
public class Employee < public Gender gender; > public class Example < @Test public void convertsMapToEmployee() < MapString, Object> employeeMap = singletonMap("gender", 1); MapToObjectConverter converter = new MapToObjectConverter(); converter.registerConverter(Gender.class, number -> Gender.fromInt((int) number)); Employee employee = converter.convert(employeeMap, Employee.class); assertEquals(Gender.FEMALE, employee.gender); > >
Registering single value converters for optional fields
Registering converts for optional fields works in the same way — we register converter for Gender.class , not for Optional.class . The registered converter has to handle null, but a value returned by it will be automatically wrapped into Optional :
public class Employee < public final OptionalGender> gender; public Employee(Gender gender) < this.gender = Optional.ofNullable(gender); > > public class Example < @Test public void convertsMapToEmployeeWithNonNullOptionalField() < MapString, Object> employeeMap = singletonMap("gender", 0); MapToObjectConverter converter = new MapToObjectConverter(); converter.registerConverter(Gender.class, number -> number == null ? null : Gender.fromInt((int) number)); Employee employee = converter.convert(employeeMap, Employee.class); assertEquals(Optional.of(Gender.MALE), employee.gender); > @Test public void convertsMapToEmployeeNullOptionalField() < MapString, Object> employeeMap = singletonMap("gender", null); MapToObjectConverter converter = new MapToObjectConverter(); converter.registerConverter(Gender.class, number -> number == null ? null : Gender.fromInt((int) number)); Employee employee = converter.convert(employeeMap, Employee.class); assertEquals(Optional.empty(), employee.gender); > >
Key case insensitive mode
By default, keys of the map and fields’ name are case sensitive, so if the map contains two keys abc and aBC , and target class contains two fields with names abc and aBC , the conversion will be successful:
public class Data < public int abc; public int aBC; > public class Example < @Test public void convertsToObjectInCaseSensitiveMode() < MapString, Object> dataMap = new HashMap<>(); dataMap.put("abc", 1); dataMap.put("aBC", 2); MapToObjectConverter converter = new MapToObjectConverter(true); // keyCaseSensitive = true (default) Data data = converter.convert(dataMap, Data.class); assertEquals(1, data.abc); assertEquals(2, data.aBC); // multiple assertions give poor diagnostics, use shazamcrest instead > >
However, in key case insensitive mode this will throw the exception as keys abc and aBC are considered duplicates:
public class Example < @Rule public final ExpectedException expectedException = ExpectedException.none(); @Test public void throwsExceptionForDuplicateKeysInCaseInsensitiveMode() < MapString, Object> dataMap = new HashMap<>(); dataMap.put("abc", 1); dataMap.put("aBC", 2); MapToObjectConverter converter = new MapToObjectConverter(false); // keyCaseSensitive = false expectedException.expect(ConverterIllegalArgumentException.class); expectedException.expectMessage(equalTo("Keys 'abc', 'aBC' are duplicates (converter is key case insensitive).")); converter.convert(dataMap, Data.class); > >
Key case insensitive mode allows to ignore the casing of fields and keys when converting map to object. In key case sensitive mode the below example would throw the exception, as the map is missing values for fields abc and aBC while the target class is missing a field for key ABC .
public class Example < @Test public void convertsToObjectInCaseInsensitiveMode() < MapString, Object> dataMap = singletonMap("ABC", 7); MapToObjectConverter converter = new MapToObjectConverter(false); // keyCaseSensitive = false Data data = converter.convert(dataMap, Data.class); assertEquals(7, data.abc); assertEquals(7, data.aBC); // multiple assertions give poor diagnostics, use shazamcrest instead > >
- assigns the values from the map to fields whose names are equal to the keys
- throws exception if there are entries without corresponding fields (of course listing the keys)
- throws exception if there are fields for which there were no values (of course listing names of all such fields)
- assigns the fields regardless of their access modifier and final keyword – no methods or annotations are required in the class
- creates the instance of the class without calling its constructor so you have a complete freedom in how you want to define the class
- differs between no value for key or value being null
- requires the field to be Optional if the value is null, so once we have the staticly typed class, we know there are no nulls
- it checks the type of field and value, also in case of Optional fields
- can map String values to enums (using static valueOf(String) method)
- allows to register type converters so you can convert String to enum using different method than valueOf , or you can convert int to enum
- allows the fields to be supertypes of values, so you can assign Integer value to Number field
- allows to ignore case of keys in the map
- unfortunately, it doesn’t allow wildcards in Optionals , so Integer value can be assigned to Optional field but cannot be assigned to field declared as Optional (this might be improved in future)
- doesn’t allow raw Optionals
Just add a Maven dependency to your pom file:
uk.co.jpawlak map-to-object-converter 3.0