Not sure about Singleton - java

If I have a singleton class like:
public class MySingleton(){
private static MySingleton istance;
private int element;
private MySingleton(){element = 10;}
public static MySingleton getIstance() {
if(istance == null)
istance = new Mysingleton();
return istance;
}
public void setElement(int i ){
element = i;
}
public int getElement(){
return element;
}
}
and I want to change element's value by calling
MySingleton.getIstance().setElement(20)
Will it change the element value for the istance? Here's an example:
... main () {
MySingleton.getIstance().setElement(20);
System.out.prinln(MySingleton.getIstance().getElement());
// It displays 10, why ?

I suggest you use an enum as it is simpler and thread safe (but not your getter/setter)
public enum MySingleton() {
INSTANCE;
private int element = 10;
public void setElement(int element) { this.element = element; }
public int getElement() { return element; }
}
MySingleton.INSTANCE.setElement(20);
System.out.prinln(MySingleton.INSTANCE.getElement()); // prints 20.

I'm not sure if your code block above was copied in or just retyped, but there were a few basic compilation issues I saw with it - when you're setting MySingleton in getInstance, you need to check capitalization. Also, your class declaration shouldn't have (parentheses). After fixing these two things and running basic main, I got 20.
This is the same as what you had - no synchronization or anything else, but on a single thread it doesn't seem necessary.
public class MySingleton{
private static MySingleton istance;
private int element;
private MySingleton(){element = 10;}
public static MySingleton getIstance() {
if(istance == null)
istance = new MySingleton();
return istance;
}
public void setElement(int i ){
element = i;
}
public int getElement(){
return element;
}
public static void main(String[] args) {
System.out.println(MySingleton.getIstance().getElement());
MySingleton.getIstance().setElement(20);
System.out.println(MySingleton.getIstance().getElement());
}
}
should have an output of
10
20

Im not sure if your code really work, how azurefrog say, make your code synchronized, and in youre line public static getIstance() { you need to set the return type.

Related

Android, couldn't make static getter setter property work?

I was trying this ...
public class Info {
private static Info ourInstance = new Info();
public static Info getInstance() { return ourInstance; }
private static int currentIndex;
public static void setCurrentIndex(int i) {
Log.d("DEV", "setter!");
currentIndex = i;
// do other work here
}
public static int getCurrentIndex() {
Log.d("DEV", "getter!");
return currentIndex;
}
private Info() {
Log.d("DEV", "class initialized no problem...");
currentIndex = 42; // just doesn't work, only sets the field
}
}
in any other class...
Info.currentIndex = 666; // just doesn't work
It just doesn't work - what could the problem be? Tried everything.
Why do you define the setter/getter if you are going to end up doing this?
Info.currentIndex = 666;
if so, then change currentIndex visibility to public...
or even better, be congruent with the code and do
Info.setCurrentIndex(666);

How to pass a parameter in a fluent API before calling any function?

I have this kind of class
public class AImpl implements A {
private String variable = "init";
#Override
public A choice(A... choices) {
return this;
}
#Override
public A execute() {
variable = "execute";
return this;
}
}
I can use it like this (simple example)
new AImpl().choice(
new AImpl[] {
new AImpl().execute(),
new AImpl()
};
)
or like this (more complex example, with variable expected value)
new AImpl().choice( //variable == "init"
new AImpl[] {
new AImpl().execute(), //variable == "init". Set to "execute"
new AImpl().choice( //variable == "init"
new AImpl[] {
new AImpl() //variable == "init"
}
),
new AImpl().execute().choice( //variable == "init". Set to "execute"
new AImpl[] {
new AImpl(), //variable == "execute"
new AImpl() //variable == "execute"
}
),
};
)
What I'm trying to achieve
Each time there is a choice, I would like to propagate the last value of variable to each new instances. Here is graph version of the complex example where I encircled what I called propagation
What is my question
How can I propagate this variable to all the objects in the choices list before calling any other function (before calling execute in the simple example above, because this function uses (and can modify) this variable).
What I have tried
I can not do it using the constructor since I don't have a reference to the variable
public AImpl(String variable) {
this.variable = variable;
}
This code will not work because the variable will be set after all functions
#Override
public A choice(A... choices) {
for(A a : choices) {
a.setVariable(variable);
}
}
I tried with a Builder (eg set all the values and only create the instance at the end, from the choice function for example). But it make sense to chained the functions execute or choice (...execute().execute().choice()...). So the builder become difficult to create and can become really big.
I also tried to move the variable to a context class, but it is not working if in the choices I have another choice (case of the more complex example). Here is my current context class
public class Context {
private static Context instance = null;
private String variable;
private Context(){};
public String getVariable() {
return variable;
}
public void setVariable(String variable) {
this.variable = variable;
}
public static void set(String variable) {
if(Context.instance == null)
Context.instance = new Context();
Context.instance.setVariable(variable);
}
public static String get() {
if(Context.instance == null)
throw new NullPointerException();
return Context.instance.getVariable();
}
}
The problem is that new AImpl instances need to inherit the context of their "parent" AImple instance, i.e. the one on which choice() is called. You can't do that using the new operator. You should instead have a method that creates the instances with an inherited variable.
public A[] createChoices(int count, A optionalDefaultValues...) {
// return an array of clones of itself (possibly with adjusted defaults)
}
I finally found a working solution based on the Context approach (see What I have tried ?)
The main idea
There are two mains ideas. The first one is to replace (inside the context object) the single variable by a Stack of variables like this one
Stack<String> variables = new Stack<>();
I push the first variable in the first constructor and them I can access and modify it using pop/push function
String variable = Context.pop();
//Do something with variable
Context.push("anotherValue");
The second main idea is to duplicate the value on the top of the stack each time I create a new choice and to remove it at the end of each choice.
My code
Here is my code, if it can help someone else. I'm sure there is a lot of things to do to improve it, but it solved my original problem.
TestSo.java
public class TestSo {
#Test
public void testSo() {
AImpl.create().choice(
new ChoiceList()
.add(AChoice.create().execute())
.add(AChoice.create().choice(
new ChoiceList().add(AChoice.create())
))
.add(AChoice.create().execute().choice(
new ChoiceList()
.add(AChoice.create())
.add(AChoice.create())
))
);
}
}
A.java
public interface A {
A choice(ChoiceList choices);
A execute();
}
AAbstract.java
public class AAbstract implements A {
#Override
public A choice(ChoiceList choices) {
return this;
}
#Override
public A execute() {
String variable = Context.get();
//...
Context.set("execute");
return this;
}
}
AImpl.java
public class AImpl extends AAbstract {
private AImpl() {
Context.set("init");
}
public static AImpl create() {
return new AImpl();
}
}
AChoice.java
public class AChoice extends AAbstract {
private AChoice() {
Context.duplicate();
}
public static AChoice create() {
return new AChoice();
}
#Override
public AChoice choice(ChoiceList choices) {
super.choice(choices);
return this;
}
#Override
public AChoice execute() {
super.execute();
return this;
}
}
ChoiceList.java
public class ChoiceList {
private List<AChoice> choices = new ArrayList<>();
public ChoiceList add(AChoice choice) {
Context.remove();
choices.add(choice);
return this;
}
}
Context.java
public class Context {
private static Context instance = null;
private Stack<String> variables = new Stack<>();
private Context(){};
public String peek() {return variables.peek();}
public String pop() {return variables.pop();}
public void fork() {variables.push(variables.peek());}
public void push(String variable) {variables.push(variable);}
public static void set(String variable) {
if(Context.instance == null)
Context.instance = new Context();
Context.instance.push(variable);
}
public static String get() {
if(Context.instance == null)
throw new NullPointerException();
return Context.instance.pop();
}
public static void remove() {
if(Context.instance == null)
throw new NullPointerException();
Context.instance.pop();
}
public static void duplicate() {
if(Context.instance == null)
throw new NullPointerException();
Context.instance.fork();
}
public static String read() {
if(Context.instance == null)
throw new NullPointerException();
return Context.instance.peek();
}
}

How do you insure mutual exclusion for data structures?

I heard the same rule that applies for variables doesn't apply when we're talking about data structures. Is this true?
For instance, this, which is perfectly fine
public class SynchronizedCounter {
private int c = 0;
public synchronized void increment() {
c++;
}
public synchronized void decrement() {
c--;
}
public synchronized int value() {
return c;
}
}
does not mean that the following will work flawlessly.
public class SynchronizedDataStructures {
private ArrayList<String> c = new ArrayList<String>();
public synchronized void add1(element) {
c.add(element);
}
public synchronized void clear1() {
c.clear();
}
public synchronized int value() {
return c;
}
}
Is this true and what can I do to make it work for data structures?
If you change add1(element) to add1(String element), and remove the value() method, this will compile, and be thread safe.
You will need a method which correctly accessing the contents of the list. e.g.
public synchronized int value(int index) {
return c.get(index);
}
There is a more clean way to synchronize on an object and not on a complete method. Consider this:
...
public void clear1() {
synchronized(c) {
c.clear();
}
}
...
http://tutorials.jenkov.com/java-concurrency/synchronized.html
This is a nice explanation of synchronized in Java.

When instantiating a method that returns a variable...?

Basically, I want to make sure that I'm doing this right. I'm calling these methods in another class. The methods specify to return a variable, so when instantiating them, should I be placing null in the parenthesis? I just want to make sure I'm doing this right.
public class IntSLList {
protected static IntSLLNode head, tail;
public void createInst(){
new IntSLList().isEmpty();
new IntSLList().addToHead(null);
new IntSLList().addToTail(null,null);
new IntSLList().deleteFromTail();
new IntSLList().printAll();
new IntSLList().isInList(null);
new IntSLList().delete(null);
}
public IntSLList() {
//code
}
public static boolean isEmpty() {
//code }
public static void addToHead(String AN) {
//code
}
public static void addToTail(String AN, Double AB) {
//code
}
public static String deleteFromHead() { // delete the head and return its info;
//code
}
public static String deleteFromTail() { // delete the tail and return its info;
//code
}
public static void printAll() {
//code
}
public static boolean isInList(String AN) {
//code
}
public static void delete(String AN){
//code
}}
Thanks everyone in advance!
You don't need to instantiate methods at all, they are already "prepared for use" when your list gets instantiated.
What you want to do is remove the static keyword from the methods: It means that the methods are defined "global" for the whole class instead of just for one specific list.
Update: This is the list class as I imagine it should be
import java.util.ArrayList;
public class IntSLList {
protected int head,tail;
//I'll use this as examplelist, so I can omit the list implementation
private ArrayList<Integer> dataList;
public IntSLList(){
//Do initalization
dataList = new ArrayList<>();
}
public void addToHead(int node){
dataList.add(0, node);
}
public void addToTail(int node){
dataList.add(node);
}
public boolean isEmpty(){
return dataList.isEmpty();
}
// ... snip other list methods here ...
}
You can use/access it like this:
public class ListMain {
public static void main(String[] args){
IntSLList myList = new IntSLList();
myList.addToHead(1);
myList.addToTail(2);
System.out.println("myList.isEmpty() = " + myList.isEmpty());
}
}

Null pointer exception on getter setter in java

I have a getter setter class named SharedData.java . I am getting null pointer exception when I'm going to imply it on my code . Here is the SharedData class :
public class SharedData {
private static SharedData instance = null;
public SharedData() {
// randomizeServers();
}
// data to be shared
private double src_latitude = -1;
private double src_longitude = -1;
private double end_latitude = -1;
private double end_longitude = -1;
//Getter-Setters
public static SharedData getInstance() {
return instance;
}
public static void setInstance(SharedData instance) {
SharedData.instance = instance;
}
public double getSrc_latitude() {
return src_latitude;
}
public void setSrc_latitude(double src_latitude) {
this.src_latitude = src_latitude;
}
public double getSrc_longitude() {
return src_longitude;
}
public void setSrc_longitude(double src_longitude) {
this.src_longitude = src_longitude;
}
public double getEnd_latitude() {
return end_latitude;
}
public void setEnd_latitude(double end_latitude) {
this.end_latitude = end_latitude;
}
public double getEnd_longitude() {
return end_longitude;
}
public void setEnd_longitude(double end_longitude) {
this.end_longitude = end_longitude;
}
}
Here is my code :
SharedData sharedData ;
sharedData = SharedData.getInstance();
sharedData.setSrc_latitude(latitude);
sharedData.setEnd_longitude(longitude);
Can anybody please help me with this ? Thanks .
You never initialized sharedData, so its value is null, calling a method on it got your program to crash.
I think you're trying to use Singleton Pattern. Try the below:
private static SharedData instance = new SharedData(); \\ Initialize here
private SharedData() { // Make it private....
// randomizeServers();
}
// data to be shared
private double src_latitude = -1;
private double src_longitude = -1;
private double end_latitude = -1;
private double end_longitude = -1;
//Getter-Setters
public static SharedData getInstance() {
return instance;
}
SharedData.getInstance();
Returns null. Later you're trying to call a method on it:
sharedData.setSrc_latitude(latitude);
Which is illegal as reference to object is still null.
You don't instanciate the class, so getInstance() returns null.
At the start of your class, replace :
private static SharedData instance = null;
by :
private static SharedData instance = new SharedData() ; // creates a new instance
change private static SharedData instance = null;
to private static SharedData instance = this;
and make your class static
public static class SharedData {
Also , make the getters setters static..
Even using the singleton pattern you should instantiate the object SharedData at least once.
try this
SharedData sharedData = new SharedData();
sharedData = SharedData.getInstance();
sharedData.setSrc_latitude(latitude);
sharedData.setEnd_longitude(longitude);

Categories