Reputation: 27
I've defined the following set of data
Response response = new Response();
List<ObjectTest> objList = new ArrayList<ObjectTest>();
objList.add(new ObjectTest(new Attributes(new FirstName("ab","1"),new LastName("hernandez","2"))));
objList.add(new ObjectTest(new Attributes(new FirstName("jose","1"),new LastName("perez","2"))));
objList.add(new ObjectTest(new Attributes(new FirstName("paco","2"),new LastName("jackson","2"))));
objList.add(new ObjectTest(new Attributes(new FirstName("pedro","1"),new LastName("herrera","2"))));
objList.add(new ObjectTest(new Attributes(new FirstName("juan","2"),new LastName("flores","2"))));
response.setObjectList(objList);
So based on what the user selects I need to be able to get the specific class and the attribute, for example:
if the user selects [Attributes - FirstName - value] the output would be : ab jose paco pedro juan
if the user selects [Attributes - LastName- status] the output would be: 2 2 2 2 2
The problem here is that I dont know how to get the specific class in runtime. Also the main object could have any number of classes inside of it like MainClass.ClassA.ClasstB.ClassX.classAttributeValue. The only thing that I know is that the last value is going to be the one that I have to take in that case I have to print classAttributeValue . Any ideas how to solve this using java 8 ?
Upvotes: 1
Views: 790
Reputation: 27
Thank you for your responses, what I finally did was to use JsonNode and based on the attribute I wanted to get I was iterating the same object and assign the result to se same object for example:
Json Response: Object.Person1.firstName.value
I created an array of that and split it by "." then I created a for and I used this jsonNode = jsonNode.get(inputArray[x]);
at the end the last element of the array is the one that I need so I added some logic to get it.
Upvotes: 0
Reputation: 761
Assuming your class structure looks something like this:
public static abstract class Attribute {
public final String value;
public final String status;
public Attribute(String value, String status) {
this.value = value;
this.status = status;
}
}
public static class FirstName extends Attribute {
public FirstName(String value, String status) {
super(value, status);
}
}
public static class LastName extends Attribute {
public LastName(String value, String status) {
super(value, status);
}
}
public static class Attributes {
public final FirstName firstName;
public final LastName lastName;
public Attributes(FirstName firstName, LastName lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
public static class ObjectTest {
public final Attributes attributes;
public ObjectTest(Attributes attributes) {
this.attributes = attributes;
}
}
You can define java.util.function.Function
accessors for each stage:
Function<ObjectTest, Attributes> attributes = t -> t.attributes;
Function<Attributes, FirstName> firstName = t -> t.firstName;
Function<Attributes, LastName> lastName = t -> t.lastName;
Function<Attribute, String> value = t -> t.value;
Function<Attribute, String> status = t -> t.status;
And combine them like so:
Function<ObjectTest, String> attributeFirstNameValue =
attributes.andThen(firstName).andThen(value);
Function<ObjectTest, String> attributeLastNameStatus =
attributes.andThen(lastName).andThen(status);
Then apply the combined accessor to the list:
objList.stream().map(attributeFirstNameValue).forEach(System.out::println);
objList.stream().map(attributeLastNameStatus).forEach(System.out::println);
Upvotes: 2
Reputation: 1424
Is it critical to use this class structure?
In your example using a associative container is more suitable.
For example you can create class with structure like this:
Firstly you shoud something for itterate by Tree:
class DynamicObjectNode {
private HashMap<String, DynamicObjectNode> childs = new HashMap<>();
public HashMap<String, DynamicObjectNode> getChilds() {
return childs;
}
}
All values should be in leafs:
class DynamicObjectNodeValue<T> extends DynamicObjectNode {
public DynamicObjectNodeValue(T value) {
this.value = value;
}
private T value;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
@Override
public HashMap<String, DynamicObjectNode> getChilds() {
return null; //Tree leafs should not has childs
}
}
If you need to work with this as objects. You can use wrapped class like this:
class FirstNameAttribute extends DynamicObjectNode{
private static final String NameValueProperty = "NameValue";
private static final String StatusProperty = "Status";
private DynamicObjectNodeValue<String> nameValue = new DynamicObjectNodeValue<String>("Default name");
private DynamicObjectNodeValue<Integer> status = new DynamicObjectNodeValue<Integer>(1);
public FirstNameAttribute() {
getChilds().put(NameValueProperty, nameValue);
getChilds().put(StatusProperty, status);
}
public String getName() {
return nameValue.getValue();
}
public Integer getStatus() {
return status.getValue();
}
public void setName(String val) {
nameValue.setValue(val);
}
public void setStatus(Integer val) {
status.setValue(val);
}
}
So, with this code you can iterate it as a Tree and get values Dynamic.
And you can use this as objects to call some methods.
Upvotes: 1