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();
}
}
Related
I have class-Composite:
public class CompositeText implements ComponentText {
private TypeComponent type;
private String value;
private final List<ComponentText> childComponents;
private CompositeText() {
childComponents = new ArrayList<>();
}
public CompositeText(String value, TypeComponent typeComponent) {
this.value = value;
this.type = typeComponent;
childComponents = new ArrayList<>();
}
#Override
public void add(ComponentText componentText) {
childComponents.add(componentText);
}
#Override
public void remove(ComponentText componentText) {
childComponents.remove(componentText);
}
#Override
public TypeComponent getComponentType() {
return this.type;
}
#Override
public ComponentText getChild(int index) {
return childComponents.get(index);
}
#Override
public int getCountChildElements() {
return childComponents.size();
}
#Override
public int getCountAllElements() {
return childComponents.stream()
.mapToInt(ComponentText::getCountAllElements)
.sum();
}
#Override
public String toString() {
return null;
}
}
I created classes that perform the same action - parsing, parsing text into paragraphs, into sentences, into tokens, into symbols.
public class IntoParagraphParser implements ActionParser {
// call IntoSentenceParser
}
public class IntoSentenceParser implements ActionParser {
// call IntoLexemeParser
}
public class IntoLexemeParser implements ActionParser {
// call IntoSymbolParser
}
public class IntoSymbolParser implements ActionParser {
}
All data is stored in List <ComponentText> childComponents in class-Composite - CompositeText.
How to properly create a method so that it prints all the data that is inside the composite?
I think this will be the method toString() in CompositeText.
Class IntoParagraphParser look:
public class IntoParagraphParser implements ActionParser {
private static final String PARAGRAPH_SPLIT_REGEX = "(?m)(?=^\\s{4})";
private static final IntoParagraphParser paragraphParser = new IntoParagraphParser();
private static final IntoSentenceParser sentenceParser = IntoSentenceParser.getInstance();
private IntoParagraphParser() {
}
public static IntoParagraphParser getInstance() {
return paragraphParser;
}
public ComponentText parse(String text) throws TextException {
ComponentText oneParagraph;
ComponentText componentParagraph = new CompositeText(text, TypeComponent.PARAGRAPH);
String[] arrayParagraph = text.split(PARAGRAPH_SPLIT_REGEX);
for(String element: arrayParagraph) {
oneParagraph = new CompositeText(element, TypeComponent.PARAGRAPH);
oneParagraph.add(sentenceParser.parse(element));
componentParagraph.add(oneParagraph);
}
return componentParagraph;
}
}
Need #Override the method toString() in CompositeText like this:
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
for (ComponentText component : childComponents) {
builder.append(component.toString());
}
return builder.toString();
}
But how to write this code correctly with Stream API?
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
childComponents.stream().map(...????
return builder.toString();
}
I'm reading the book "Thinking in Java" by Bruce Eckel. I came across this assertion in the inner class chapter, which says: "the only justification for using a local inner class instead of an anonymous inner class is if you need a named constructor and/or an overloaded constructor"
I don't now if i understood well but:
Is this the way of overloading constructors of Inner(local classes) inside method?
abstract class ForInner {
abstract String getName();
abstract void setName(String newName);
abstract int getNumber();
abstract void setNumber(int newNumber);
}
class Outer{
public ForInner getSomeInner(String name) {
class LocalInner extends ForInner{
private String myName;
private int myNumber;
public LocalInner(String myName) {
this.myName = myName;
}
public String getName() {
return myName;
}
public void setName(String newName) {
myName = newName;
}
public int getNumber() {
return myNumber;
}
public void setNumber(int newNumber) {
myNumber = newNumber;
}
}
return new LocalInner(name);
}
public ForInner getSomeInner(int number) {
class LocalInner extends ForInner{
private String myName;
private int myNumber;
public LocalInner(int myNumber) {
this.myNumber = myNumber;
}
public String getName() {
return myName;
}
public void setName(String newName) {
myName = newName;
}
public int getNumber() {
return myNumber;
}
public void setNumber(int newNumber) {
myNumber = newNumber;
}
}
return new LocalInner(number);
}
}
I'm not sure if the assertion referring to this. But might have a guess that is not the case because How different it would be of using in this way
abstract class ForInner {
abstract String getName();
abstract void setName(String newName);
abstract int getNumber();
abstract void setNumber(int newNumber);
}
lass Outer{
public ForInner inner (String name) {
return new ForInner() {
private String myName;
private int myNumber;
{
myName = name;
}
public String getName() {
return myName;
}
public void setName(String newName) {
myName = newName;
}
public int getNumber() {
return myNumber;
}
public void setNumber(int newNumber) {
myNumber = newNumber;
}
};
}
public ForInner inner (int number) {
return new ForInner() {
private String myName;
private int myNumber;
{
myNumber = number;
}
public String getName() {
return myName;
}
public void setName(String newName) {
myName = newName;
}
public int getNumber() {
return myNumber;
}
public void setNumber(int newNumber) {
myNumber = newNumber;
}
};
}
}
thank in advance?
public class OuterClass {
Runnable printA = new Runnable() {
#Override
public void run() {
System.out.println("Print A");
}
};
Runnable printB = new Runnable() {
#Override
public void run() {
System.out.println("MESSAGE:" + " " + "Print B");
}
};
class PrintMessage implements Runnable {
private String msg;
public PrintMessage(String msg) {
this.msg = msg;
}
// overloaded constructor
public PrintMessage(String prefix, String msg) {
this.msg = prefix + " " + msg;
}
#Override
public void run() {
System.out.println(msg);
}
}
Runnable printC = new PrintMessage("Print C");
Runnable printD = new PrintMessage("Print D");
Runnable printE = new PrintMessage("MESSAGE:", "Print E");
public static void main(String[] args) {
OuterClass sample = new OuterClass();
sample.printA.run();
sample.printB.run();
sample.printC.run();
sample.printD.run();
sample.printE.run();
}
}
There are two instances of Runnable implemented as anonymous classes. While printA is created you cannot use it to create printB. You should create anonymous class from the beginning (i.e. override all abstract methods).
If an inner class created based on Runnable, you can use it in form new PrintMessage() to create new instances. Besides that it's possible to use non-default constructors.
Ah ok so when have this code
class OuterClass {
public Runnable printA() {
return new Runnable() {
#Override
public void run() {
System.out.println("Print A");
}
};
}
public static void main(String[] args) {
OuterClass outer = new OuterClass();
Runnable printA = outer.printA();
Runnable printB = outer.printA();
}
}
In this case I'm not creating multiply instances of a single anonymous inner class. Instead I'm creating multiple anonymous classes that use the same source code. Is that Rigth?!
Thanks
I'm familiar with using the builder pattern with generics and subclassing, but I can't see how to make it work with a non-trivial tree of subclasses (i.e. C extends B extends A). Here's a simple example of what I'm trying to do:
class A {
private final int value;
protected A(ABuilder builder) {
this.value = builder.value;
}
public int getValue() { return value; }
public static class ABuilder<T extends ABuilder<T>> {
private int value;
public T withValue(int value) {
this.value = value;
return (T) this;
}
public A build() {
return new A(this);
}
}
}
class B extends A {
private final String name;
public static BBuilder builder() {
return new BBuilder();
}
protected B(BBuilder builder) {
super(builder);
this.name = builder.name;
}
public String getName() { return name; }
public static class BBuilder<U extends BBuilder<U>> extends ABuilder<BBuilder<U>> {
private String name;
public U withName(String name) {
this.name = name;
return (U) this;
}
public B build() {
return new B(this);
}
}
}
Everything is fine if I declare BBuilder without the generic type:
public static class BBuilder extends ABuilder<BBuilder>
Since I want BBuilder to be extended by a CBuilder, I'm trying to use the same sort of Curiously Recurring Template Pattern as ABuilder. But like this, the compiler sees BBuilder.withValue() as returning an ABuilder, not a BBuilder as I want. This:
B b = builder.withValue(1)
.withName("X")
.build();
doesn't compile. Can anyone see what I'm doing wrong here, I've been going round trying different patterns of generics but can't get it to work.
Thanks to anyone who has any advice.
It seems that your mistake only with declaring correct parameter:
class A {
private final int value;
public static <T extends Builder<T>> T builderA() {
return (T)new Builder<>();
}
protected A(Builder<? extends Builder<?>> builder) {
value = builder.value;
}
public static class Builder<T extends Builder<T>> {
private int value;
public T withValue(int value) {
this.value = value;
return (T)this;
}
public A build() {
return new A(this);
}
}
}
class B extends A {
private final String name;
public static <T extends Builder<T>> T builderB() {
return (T)new Builder<>();
}
protected B(Builder<? extends Builder<?>> builder) {
super(builder);
name = builder.name;
}
public static class Builder<T extends Builder<T>> extends A.Builder<T> {
private String name;
public Builder<T> withName(String name) {
this.name = name;
return this;
}
public B build() {
return new B(this);
}
}
}
Client code:
A a = A.builder().withValue(1).build();
B b = B.builder().withValue(2).withName("xx").build();
Are you certain you need generics? This hierarchy seems to work fine without generics.
static class A {
protected final int value;
protected A(ABuilder builder) {
this.value = builder.value;
}
public int getValue() {
return value;
}
#Override
public String toString() {
return "A{" +
"value=" + value +
'}';
}
public static ABuilder builder() {
return new ABuilder();
}
public static class ABuilder {
protected int value;
public ABuilder withValue(int value) {
this.value = value;
return this;
}
public A build() {
return new A(this);
}
}
}
static class B extends A {
protected final String name;
protected B(BBuilder builder) {
super(builder);
this.name = builder.name;
}
public String getName() {
return name;
}
#Override
public String toString() {
return "B{" +
"value=" + value +
", name='" + name + '\'' +
'}';
}
public static BBuilder builder() {
return new BBuilder();
}
public static class BBuilder extends ABuilder {
private String name;
public BBuilder withName(String name) {
this.name = name;
return this;
}
#Override
public BBuilder withValue(int value) {
this.value = value * 2;
return this;
}
public B build() {
return new B(this);
}
}
}
static class C extends B {
private final String otherName;
protected C(CBuilder builder) {
super(builder);
this.otherName = builder.otherName;
}
public String getName() {
return otherName;
}
#Override
public String toString() {
return "C{" +
"value=" + value +
", name='" + name + '\'' +
", otherName='" + otherName + '\'' +
'}';
}
public static CBuilder builder() {
return new CBuilder();
}
public static class CBuilder extends BBuilder {
private String otherName;
public CBuilder withName(String name) {
this.otherName = name;
return this;
}
public C build() {
return new C(this);
}
}
}
public void test() {
A a = A.builder().withValue(10).build();
B b = B.builder().withValue(10).withName("B").build();
C c = C.builder().withName("C").build();
System.out.println("a = "+a);
System.out.println("b = "+b);
System.out.println("c = "+c);
}
I'm trying to store a coordnates (array of double) using Realm-java,but I'm not able to do it.
Here is an example of json that I'm trying to parse:
{"_id":"597cd98b3af0b6315576d717",
"comarca":"string",
"font":null,
"imatge":"string",
"location":{
"coordinates":[41.64642,1.1393],
"type":"Point"
},
"marca":"string",
"municipi":"string",
"publisher":"string",
"recursurl":"string",
"tematica":"string",
"titol":"string"
}
My global object code is like that
public class Images extends RealmObject implements Serializable {
#PrimaryKey
private String _id;
private String recursurl;
private String titol;
private String municipi;
private String comarca;
private String marca;
private String imatge;
#Nullable
private Location location;
private String tematica;
private String font;
private String parentRoute;
public Location getLocation() {return location;}
public void setLocation(Location location) {this.location = location;}
public String getParentRoute() {
return parentRoute;
}
public void setParentRoute(String parentRoute) {
this.parentRoute = parentRoute;
}
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
public String getFont() {
return font;
}
public void setFont(String font) {
this.font = font;
}
public String getRecursurl() {
return recursurl;
}
public void setRecursurl(String recursurl) {
this.recursurl = recursurl;
}
public String getTitol() {
return titol;
}
public void setTitol(String titol) {
this.titol = titol;
}
public String getMunicipi() {
return municipi;
}
public void setMunicipi(String municipi) {
this.municipi = municipi;
}
public String getComarca() {
return comarca;
}
public void setComarca(String comarca) {
this.comarca = comarca;
}
public String getMarca() {
return marca;
}
public void setMarca(String marca) {
this.marca = marca;
}
public String getImatge() {
return imatge;
}
public void setImatge(String imatge) {
this.imatge = imatge;
}
public String getTematica() {
return tematica;
}
public void setTematica(String tematica) {
this.tematica = tematica;
}
And Location is a composite of type and a realmlist
Location.java
public class Location extends RealmObject implements Serializable {
private String type;
private RealmList<RealmDoubleObject> coordinates;
public Location() {
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public RealmList<RealmDoubleObject> getCoordinates() {
return coordinates;
}
public void setCoordinates(RealmList<RealmDoubleObject> coordinates) {
this.coordinates = coordinates;
}
}
RealmDoubleObject.java
public class RealmDoubleObject extends RealmObject implements Serializable{
private Double value;
public RealmDoubleObject() {
}
public Double getDoublevalue() {
return value;
}
public void setDoublevalue(Double value) {
this.value = value;
}
}
The error is com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was NUMBER at path $[0].location.coordinates[0] but I'm not able to figure out why this number is not "fitting" by RealmDoubleObject.
For those that not familiar with realm RealmList doesn't work and you have to build your own realm object.
Thank you. I hope to find some Realm experts here!
SOLVED:
using Gson deserializer it can be done
First we have to initialize the gson object like this
Gson gson = new GsonBuilder()
.setExclusionStrategies(new ExclusionStrategy() {
#Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getDeclaringClass().equals(RealmObject.class);
}
#Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
})
.registerTypeAdapter(new TypeToken<RealmList<RealmDoubleObject>>() {}.getType(), new TypeAdapter<RealmList<RealmDoubleObject>>() {
#Override
public void write(JsonWriter out, RealmList<RealmDoubleObject> value) throws IOException {
// Ignore
}
#Override
public RealmList<RealmDoubleObject> read(JsonReader in) throws IOException {
RealmList<RealmDoubleObject> list = new RealmList<RealmDoubleObject>();
in.beginArray();
while (in.hasNext()) {
Double valor = in.nextDouble();
list.add(new RealmDoubleObject(valor));
}
in.endArray();
return list;
}
})
.create();
And then we have to put some other constructor method
public RealmDoubleObject(double v) {
this.value = v;
}
and this is all.
Thanks for the help #EpicPandaForce
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.