This is array list model class. Is it right or wrong? I can not access this class from another class
public class CartOrder {
List<CartOrder.Data> data;
public List<Data> getData() {
return data;
}
public void setData(List<Data> data) {
this.data = data;
}
class Data {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
If you would have read the exception properly, then you would have also read the solution to your problem. You need to instantiate CartOrder object first on which you then can call s.new Data() as seen below
public static void main(String[] args) {
CartOrder s = new CartOrder();
Data d = s.new Data();
d.setName("Test");
s.addData(d);
System.out.println(s);
}
Modified your existing class:
public class CartOrder {
List<Data> data;
public CartOrder () {
data = new ArrayList<Data>();
}
public List<Data> getData() {
return data;
}
public void setData(List<Data> data) {
this.data = data;
}
public void addData(Data data) {
this.data.add(data);
}
class Data {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
similar question here
But yes your code is accurate. If you make your member property private Data::name then it cannot be accessed by anything but the factory class (class Data). Same would be true for your other function and its member.
I'm assuming you want to use it like:
CartOrder.Data data = new CartOrder.Data();
In order for that to work you should make you inner class static, so you code would become
public class CartOrder {
List<CartOrder.Data> data;
public List<Data> getData() {
return data;
}
public void setData(List<Data> data) {
this.data = data;
}
static class Data {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
After that you can use this like:
public void someMethodInSomeOtherClass() {
// ...
CartOrder cartOrder = new CartOrder();
CartOrder.Data someData = new CartOrder.Data();
someData.setName("Luke");
CartOrder.Data moreData = new CartOrder.Data();
moreData.setName("Han");
cartOrder.setData(Arrays.asList(someData, moreData));
// ...
}
Related
I get Null Pointer Exception when running the code below:
public class Engine{
private String name = null;
private Mercedes m = null;
private Engine() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Mercedes getM() {
return m;
}
public void setM(Mercedes m) {
this.m = m;
}
public static EngineBuilder builder() {
return new EngineBuilder();
}
public static class EngineBuilder {
private Engine e = null;
public EngineBuilder builder() {
e = new Engine();
return this;
}
public Engine build() {
return this.e;
}
public EngineBuilder setName(String name) {
this.e.setName(name);
return this;
}
public EngineBuilder setM(Mercedes m) {
this.e.setM(m);
return this;
}
}
public static void main(String[] args) {
EngineBuilder builder = Engine.builder();
builder.setName("test");
Engine e = builder.build();
}
}
}
I expected the Builder pattern would work, but I got
"Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Engine.setName(String)" because "this.e" is null"
In your code EngineBuilder class have only default constructor, Which does not initialize Engine Object. Write a constructor which initializes required objects.
The attribute Engine e in EngineBuilder is initialized only in its builder() method which is never called. There's multiple ways to fix your code although I'd implement the builder pattern in a different way:
public class Engine {
private final String name;
private Engine(Builder builder) {
this.name = builder.name;
}
public String getName() {
return name;
}
public static Builder builder() {
return new Builder();
}
#Override
public String toString() {
return name;
}
public static class Builder {
private String name;
private Builder() {
}
public Builder name(String name) {
this.name = name;
return this;
}
public Engine build() {
return new Engine(this);
}
}
public static void main(String[] args) {
Engine mercedes = Engine.builder().name("Mercedes").build();
System.out.println(mercedes); // Mercedes
}
}
If you want the instances of the Engine class to act as traditional POJOs then remove final from its attributes and add a public default constructor and setters to it.
you need add constructor in builder.
public class Engine{
private String name = null;
private Mercedes m = null;
private Engine() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Mercedes getM() {
return m;
}
public void setM(Mercedes m) {
this.m = m;
}
public static EngineBuilder builder() {
return new EngineBuilder();
}
public static class EngineBuilder {
private Engine e = null;
// you need add Constructor in Builder
public EngineBuilder(){
e = new Engine();
}
public EngineBuilder builder() {
e = new Engine();
return this;
}
public Engine build() {
return this.e;
}
public EngineBuilder setName(String name) {
this.e.setName(name);
return this;
}
public EngineBuilder setM(Mercedes m) {
this.e.setM(m);
return this;
}
}
public static void main(String[] args) {
EngineBuilder builder = Engine.builder();
builder.setName("test");
Engine e = builder.build();
}
}
I have a Class A with name and value attributes.
public class A {
private String name;
private String value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
I have another Class B, such as
public class B {
private String attribute01;
private String attribute01;
private String attribute01;
public String getAttribute01() {
return attribute01;
}
public void setAttribute01(String name) {
this.attribute01 = name;
}
...
}
I would like to return a list with A type, having attribute01 key and where value is getAttribute01() from B, such as ({attribute01, getAttribute01()},{attribute02, getAttribute02()}).
How to implement it?.
Thanks in advance.
Actually I can use a very stupid way, such as
public List<A> keyvalueList(final B objB) {
List<A> list = new ArrayList<>();
A objA = new A();
objA.setName("attribute01");
objA.setValue(objB.getAttribute01());
list.add(objA);
objA = new A();
objA.setName("attribute02");
objA.setValue(objB.getAttribute02());
list.add(objA);
...
return list;
}
Part of them hard coding, obvious it is not a smart way, any proposal.
I wrote sample code for List.Please check my code that is ok to use or not.I added another extra class C.in C,it has two attribute String nameFromA and String attFromB.You should add this C object to list.Following is sample code.
public class A {
private String name;
private String value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
public class B {
private String att1;
private String att2;
private String att3;
public String getAtt1() {
return att1;
}
public void setAtt1(String att1) {
this.att1 = att1;
}
public String getAtt2() {
return att2;
}
public void setAtt2(String att2) {
this.att2 = att2;
}
public String getAtt3() {
return att3;
}
public void setAtt3(String att3) {
this.att3 = att3;
}
}
public class C {
private String namefromA;
private String attfromB;
public String getNamefromA() {
return namefromA;
}
public void setNamefromA(String namefromA) {
this.namefromA = namefromA;
}
public String getAttfromB() {
return attfromB;
}
public void setAttfromB(String attfromB) {
this.attfromB = attfromB;
}
}
public class Test {
public static void main(String args[]){
C c = new C();
A a = new A();
B b = new B();
a.setName("A1");
b.setAtt1("100");
c.setNamefromA(a.getName());
c.setAttfromB(b.getAtt1());
List list = new ArrayList();
//use generic
list.add(c);
}
}
if you don't want to use class C,then you can use Test class like that
import java.util.ArrayList;
import java.util.List;
public class Test {
private String nameFromA;
private String valueFromB;
public Test(String nameFromA, String valueFromB) {
super();
this.nameFromA = nameFromA;
this.valueFromB = valueFromB;
}
public static void main(String args[]){
A a = new A();
B b = new B();
a.setName("A1");
b.setAtt1("100");
Test test = new Test(a.getName(),b.getAtt1());
List list = new ArrayList();
list.add(test);
}
}
This is my opinion only.Please check it is ok or not.
I get an error trying to deserializing my data structure, which is a list of items, every one of them implements an interface. In addition, one of the fields of the interface is object, and every inheritance treats this Object as different field.
After so many hours spent on this issue, any answer will be appreciated.
This is the error I receive:
Exception in thread "main" java.lang.ClassCastException:
java.lang.String cannot be cast to java.util.Map
at flexjson.factories.BeanObjectFactory.instantiate(BeanObjectFactory.java:17)
at flexjson.ObjectBinder.bind(ObjectBinder.java:86)
at flexjson.ObjectBinder.bindIntoObject(ObjectBinder.java:139)
at flexjson.factories.ClassLocatorObjectFactory.instantiate(ClassLocatorObjectFactory.java:38)
at flexjson.ObjectBinder.bind(ObjectBinder.java:86)
at flexjson.ObjectBinder.bindIntoCollection(ObjectBinder.java:101)
at flexjson.factories.ListObjectFactory.instantiate(ListObjectFactory.java:13)
at flexjson.ObjectBinder.bind(ObjectBinder.java:86)
at flexjson.ObjectBinder.bind(ObjectBinder.java:65)
at flexjson.JSONDeserializer.deserialize(JSONDeserializer.java:158)
at testSerizlizeDeserializeInterface.entryPointForTestingSerialize.main(entryPointForTestingSerialize.java:34)
I made an example if anyone would like to try and play with it as well...
The interface
The EPersonType
The inheritance
The main class
The output
Thanks!
The interface
public interface IPerson {
EPersonType getPersonType();
String getName();
void setName(String name);
int getAge();
void setAge(int age);
Object getValue();
void setValue(Object value);
}
Its a pretty straightforward interface. The tricky part, as I already mentioned, is that the value represented as an Object, will contain different values based on interface implementation.
EPersonType
public enum EPersonType {
Father,
Mother,
}
The inheritance
public class Father implements IPerson {
private String name;
private int age;
private String value;
#Override
public String getName() {
return name;
}
#Override
public void setName(String name) {
this.name = name;
}
#Override
public int getAge() {
return age;
}
#Override
public void setAge(int age) {
this.age = age;
}
#Override
public Object getValue() {
return value;
}
#Override
public void setValue(Object value) {
this.value = (String) value;
}
#Override
public EPersonType getPersonType() {
return EPersonType.Father;
}
}
And another instance
public class Mother implements IPerson {
private String name;
private int age;
private boolean value;
#Override
public String getName() {
return name;
}
#Override
public void setName(String name) {
this.name = name;
}
#Override
public int getAge() {
return age;
}
#Override
public void setAge(int age) {
this.age = age;
}
#Override
public Object getValue() {
return value;
}
#Override
public void setValue(Object value) {
this.value = (boolean) value;
}
#Override
public EPersonType getPersonType() {
return EPersonType.Mother;
}
}
The main class
public class entryPointForTestingSerialize {
public static void main(String[] args) {
List<IPerson> family = new ArrayList<IPerson>();
IPerson father = new Father();
father.setAge(50);
father.setName("Oz");
father.setValue("Hello");
IPerson mother = new Mother();
mother.setAge(50);
mother.setName("Mother");
mother.setValue(false);
family.add(father);
family.add(mother);
String serialized = new JSONSerializer().deepSerialize(family);
System.out.println(serialized);
List<IPerson> deserialized = (List<IPerson>) new flexjson.JSONDeserializer<List<IPerson>>()
.use("values", new TypeLocator<String>("personType")
.add("Mother", Mother.class).add("Father", Father.class))
.deserialize(serialized);
System.out.println(deserialized);
}
}
The output
[{"age":50,"class":"testSerizlizeDeserializeInterface.Father","name":"Oz","personType":"Father","value":"Hello"},{"age":50,"class":"testSerizlizeDeserializeInterface.Mother","name":"Mother","personType":"Mother","value":false}]
Thanks!
Ozrad.
I solved it by changing the infrastructure to a better one, from my perspective. Its name is XStream and it handled everything smoothly and quickly. These lines of code, and it was all done:
XStream xstream = new XStream(new DomDriver()); // does not require XPP3 library
String xml = xstream.toXML(family);
and to get the data back:
List<IPerson> familyAfterSerialize = (List<IPerson>)xstream.fromXML(xml);
I'm being given a Json file with the form:
{
"descriptions": {
"desc1": "someString",
"desc2": {"name":"someName", "val": 7.0}
}
}
I have the POJO:
public class CustomClass {
Map<String, Object> descriptions;
public static class NameVal{
String name;
double val;
public NameVal(String name, double val){...}
}
}
I can recreate the json file with the code:
CustomClass a = new CustomClass();
a.descriptions = new HashMap<String, Object>();
a.descriptions.put("desc1", "someString");
a.descriptions.put("desc2", new CustomClass.NameVal("someName", 7.0));
new ObjectMapper().writeValue(new File("testfile"), a);
But, when I read the object back in using:
CustomClass fromFile = new ObjectMapper().readValue(new File("testfile"), CustomClass.class);
then fromFile.descriptions.get("desc2") is of type LinkedHashMap instead of type CustomClass.NameVal.
How can I get Jackson to properly parse the type of the CustomClass.NameVal descriptors (other than making some class that wraps the parsing and explicitly converts the LinkedHashMap after Jackson reads the file)?
Try this. Create a class Description with name and value attributes:
public class Description {
private String name;
private double val;
}
Now in your CustomClass do this:
public class CustomClass {
List<Description> descriptions;
}
And that's it. Remember to create getters and setters because Jackson needs it.
You could try something like this:
public class DescriptionWrapper {
private Description descriptions;
public Description getDescriptions() {
return descriptions;
}
public void setDescriptions(Description descriptions) {
this.descriptions = descriptions;
}
}
public class Description {
private String desc1;
private NameValue desc2;
public String getDesc1() {
return desc1;
}
public void setDesc1(String desc1) {
this.desc1 = desc1;
}
public NameValue getDesc2() {
return desc2;
}
public void setDesc2(NameValue desc2) {
this.desc2 = desc2;
}
}
public class NameValue {
private String name;
private double val;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getVal() {
return val;
}
public void setVal(double val) {
this.val = val;
}
}
Listing:
import java.util.List;
public class Listing<T> {
List<Thing<T>> children;
public List<Thing<T>> getChildren() {
return children;
}
public void setChildren(List<Thing<T>> children) {
this.children = children;
}
}
Thing:
public class Thing<T> {
private String type;
private T data;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Link:
public class Link {
private String author;
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
and here's an example of serialization and deserialization...
public static void main(String[] args) throws IOException {
Link link1 = new Link();
link1.setAuthor("JohnDoe");
Link link2 = new Link();
link2.setAuthor("MaryJane");
List<Thing<Link>> things = new ArrayList<Thing<Link>>();
Thing<Link> thing1 = new Thing();
thing1.setData(link1);
thing1.setType("t3");
Thing<Link> thing2 = new Thing();
thing2.setData(link2);
thing2.setType("t3");
things.add(thing1);
things.add(thing2);
Listing<Link> listing = new Listing<Link>();
listing.setChildren(things);
Thing<Listing> thing = new Thing<Listing>();
thing.setType("listing");
thing.setData(listing);
File jsonFile = new File("src/testMap.txt");
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(jsonFile, thing);
//String jsonString = "{\"type\":\"listing\",\"data\":{\"children\":[{\"type\":\"t3\",\"data\":{\"author\":\"JohnDoe\"}},{\"type\":\"t3\",\"data\":{\"author\":\"MaryJane\"}}]}}";
JavaType jsonType = mapper.getTypeFactory().constructParametricType(Thing.class, Listing.class);
Thing<Listing> readThing = mapper.readValue(jsonFile, jsonType);
}
The problem that I'm having is that the Things contained in the Listing in the sample code above are not parametrized with Link, so their data field is returned as an Object (which is actually LinkedHashMap).
I want to be able to do something like this:
List<Thing<Link>> readListingChildren = readThing.getData().getChildren();
String author = readListingChildren.get(0).getData().getAuthor();
My question is, how would I get this to work using Jackson json?
Note: there will be multiple different types of objects contained by Things, and a Thing's data member's type is defined (or should be defined) by the data object's "type" field, using strings such as t1, t2, t3, etc. which map to different classes.
To achieve a serialized String like
{
"data":{
"type":"listing",
"children":[
{
"data":{
"type":"t3",
"author":"JohnDoe"
}
},
{
"data":{
"type":"t3",
"author":"MaryJane"
}
}
]
}
}
and to use the type information to correctly deserialize the concrete class you may use
#JsonTypeName("listing")
public class Listing<T> {
List<Thing<T>> children;
public List<Thing<T>> getChildren() {
return children;
}
public void setChildren(final List<Thing<T>> children) {
this.children = children;
}
}
public class Thing<T> {
private T data;
#JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
#JsonSubTypes({
#JsonSubTypes.Type(Link.class),
#JsonSubTypes.Type(Listing.class)
})
public T getData() {
return data;
}
public void setData(final T data) {
this.data = data;
}
}
#JsonTypeName("t3")
public class Link {
private String author;
public String getAuthor() {
return author;
}
public void setAuthor(final String author) {
this.author = author;
}
}