When running my MVC model application, a Singleton instance of ApplicationModel is created.
When running the main method in my controller class, a List<Shop> is assigned to shops using setShops(). If shopsDefault = null, setShops() will also continue to assign the same List<Shop> to shopsDefault.
So far, so good.
However, when I call sortShopsByName() - which as you can see below uses setShops() - both shops AND shopsDefault become sorted! Why does it not just sort shops as intended?
My ApplicationModel Class...
import java.util.*;
public class ApplicationModel {
//static variables
private static ApplicationModel instance = null;
//instance variables
private List<Shop> shops;
private List<Shop> shopsDefault;
//constructors
private ApplicationModel() {}
//getInstance method
public static ApplicationModel getInstance() {
if (instance == null) {
instance = new ApplicationModel();
}
return instance;
}
//getters and setters
public List<Shop> getShops() {
return shops;
}
public void setShops(List<Shop> shops) {
this.shops = shops;
if (this.shopsDefault == null) {
this.shopsDefault = shops;
}
}
public List<Shop> getShopsDefault() {
return this.shopsDefault;
}
//Shop methods
public void sortShopsByName() {
List<Shop> shops = this.getShops();
Collections.sort(shops);
this.setShops(shops);
}
public void returnShopsToDefaultOrder() {
List<Shop> shopsDefault = this.getShopsDefault();
setShops(shopsDefault);
}
}
Once you assign shops to shposDefault, they both reference the same instance. Changes made to the instance via either instance will, thus, be visible via both references.
If this is not the intended behavior, you could copy the shops list when setting null. E.g.:
public void setShops(List<Shop> shops) {
this.shops = shops;
if (this.shopsDefault == null) {
this.shopsDefault = new ArrayList<>(shops);
}
}
Because it is the same list. If you want different lists, make a copy when you assign it to shopsDefault (i.e. new ArrayList<Shop>(shops)).
In this code you're setting both members to the same list reference:
this.shops = shops;
if (this.shopsDefault == null) {
this.shopsDefault = shops;
}
If you want to separate them use the following:
this.shops = shops;
if (this.shopsDefault == null) {
this.shopsDefault = new ArrayList<Shop>(shops);
}
Related
I have this code
private final Map<String, ReEncryption> reEncryptionInstances =
new HashMap<>();
public ReEncryption getReEncryptionLibInstance ()
throws ReEncryptionException
{
final String schemaName = getSchemaName();
final ReEncryption reEncryption = reEncryptionInstances.get(schemaName);
if (reEncryption != null) {
return reEncryption;
}
createReEncryptionLibInstance();
if(reEncryptionInstances.get(schemaName) == null) {
throw new ReEncryptionException(ERROR_LIBRARY_NOT_INITIALIZED);
}
return reEncryptionInstances.get(schemaName);
}
ReEncryptionInstances is a Hashmap and i want to set reEncryptionInstances.get(schemaName) == null to test my if block. How can i do that in my test class?
I can see two approaches here:
Wrap that reEncryptionInstances into a different class
Partially mock the class under test, so the createReEncryptionLibInstance does not do anything.
Option #1 would look like this:
public class YourClassUnderTest {
private final EncryptionInstances reEncryptionInstances;
public YourClassUnderTest(EncryptionInstances reEncryptionInstances) {
// You can do it in a setter too
// You can inject a Map too
this.reEncryptionInstances = reEncryptionInstances;
}
// ...
}
//...
/**
* You can also mock the EncryptionInstances class.
*/
public class TestEncryptionInstances extends EncryptionInstances {
public ReEncryption getEncryption(String schemaName) {
return null;
}
//...
}
Option #2 is generally a bad practice. So I am just pointing to Mockito.spy() and partial mocking.
I have created a class named "Global Services" which I use to save my data globally and access them in a different activity. But when I am calling the set() method, instead of overview the existing data instead it is appending that data. Below is my code.
I have even tried to remove the instance but still, it is appending the new data instead of overwriting.
import java.util.ArrayList;
import java.util.List;
public class GlobalServices {
private static GlobalServices instance;
String partner, leadsResponse;
List<Leads> assignedList = new ArrayList<>();
List<Leads> unAssignedList = new ArrayList<>();
List<Inventory> listInventory = new ArrayList<>();
private GlobalServices() {}
public static GlobalServices getInstance() {
if (instance == null) {
instance = new GlobalServices();
}
return instance;
}
public static void destory() {
instance = null;
}
public String getPartner() {
return partner;
}
public String getLeadsResponse() {
return leadsResponse;
}
public List<Leads> getAssignedList() {
return assignedList;
}
public List<Leads> getUnAssignedList() {
return unAssignedList;
}
public List<Inventory> getListInventory() {
return listInventory;
}
public void setPartner(String partner) {
this.partner = partner;
}
public void setLeadsResponse(String leadsResponse) {
this.leadsResponse = leadsResponse;
}
public void setAssignedList(List<Leads> assignedList) {
this.assignedList = assignedList;
}
public void setUnAssignedList(List<Leads> unAssignedList) {
this.unAssignedList = unAssignedList;
}
public void setListInventory(List<Inventory> listInventory) {
this.listInventory = listInventory;
}
}
The problem is that you're just assigning new references to your lists in GlobalServices but not creating new lists. This means as soon as you modify this reference from another place in your code, it will be reflected in the GlobalServices list as well. All you have to do is:
public void setAssignedList(List<Leads> assignedList) {
this.assignedList = new ArrayList<>(assignedList);
}
public void setUnAssignedList(List<Leads> unAssignedList) {
this.unAssignedList = new ArrayList<>(unAssignedList);
}
public void setListInventory(List<Inventory> listInventory) {
this.listInventory = new ArrayList<>(listInventory);
}
This way a new copy will be created in memory for each list and the data will be overwritten.
Sorry if I was wrong, but your code here is not a problem.
The problem might come from other part of your application.
The data you set might be the data that extend your current data.
Example you have
GlobalServices instance = GlobalServices.getInstance()
List<Inventory> listInventory1 = new ArrayList<>();
listInventory1.add(new Inventory());
instance.setListInventory(listInventory1); // now your inventory have one item
// In some where else in your project
List<Inventory> listInventory2 = instance.getListInventory(); // lisInventorys.size() equals 1
// Then you add more data to listInventory2 by mistake
listInventory2.add(new Inventory()); // listInventory2.size() equals 2
// Then you set back listInventory2 to your global service
instance.setListInventory(listInventory2); // now your inventory have two item
So, the data had been actually overwrite, it data just been extended by accident.
This is a continuation from what I was working in Passing 1 to many parameters of same object type
I've gotten good feedback on that , I believe i have the improved the design . The whole code is at https://github.com/spakai/flow_input_builder
The requirement is simple : -
I need to build a set of input for different workflows using 1 or more outputs from previous workflows
I have a set of interfaces
public interface SwfInput {
}
public interface SwfOutput {
}
public interface Workflow<I extends SwfInput, O extends SwfOutput> {
public O execute(I input);
}
public interface Builder<I extends SwfInput> {
public I build();
}
Now , Say I have 3 flows which gets executed in sequence FlowA->FlowB->FlowC
FlowC needs mandatory output from FlowB but only optionally from FlowA
so I have a implementation for FlowCBuilder
public class FlowCInputBuilder implements Builder<FlowCInput> {
private final FlowBOutput mandatoryflowBOutput;
private FlowAOutput optionalflowAOutput;
public FlowAOutput getOptionalflowAOutput() {
return optionalflowAOutput;
}
public FlowCInputBuilder setOptionalflowAOutput(FlowAOutput optionalflowAOutput) {
this.optionalflowAOutput = optionalflowAOutput;
return this;
}
public FlowCInputBuilder(FlowBOutput mandatoryflowBOutput) {
this.mandatoryflowBOutput = mandatoryflowBOutput;
}
#Override
public FlowCInput build() {
FlowCInput input = new FlowCInput();
input.setMandatoryFromFlowB(mandatoryflowBOutput.getOutput1FromB());
if (optionalflowAOutput != null) {
input.setOptionalFromFlowA(optionalflowAOutput.getOutput2FromA());
}
return input;
}
}
one test i have written shows an example usage
FlowBOutput mandatoryflowBOutput = new FlowBOutput();
mandatoryflowBOutput.setOutput1FromB("iNeedThis");
FlowAOutput optionalflowAOutput = new FlowAOutput();
FlowCInput input = new FlowCInputBuilder(mandatoryflowBOutput)
.setOptionalflowAOutput(optionalflowAOutput)
.build();
I have not used static inner class for the Builder pattern.
Any suggestions are welcomed.
You should use static inner class. The key point of using this approach is that, the inner can directly access private properties of the object being constructed. This helps eliminating duplicated code since the builder does not need to maintain a long list of temporary state for the constructing. So, your code can be rewritten like this:
public class FlowCInput {
private int output1FromB; // suppose that it is int
private String output2FromA; // suppose that it is String
private FlowCInput() { }
//...
public static class FlowCInputBuilder implements Builder<FlowCInput> {
private final FlowCInput result;
public FlowCInputBuilder(FlowBOutput mandatoryflowBOutput) {
result = new FlowCInput();
// output1FromB is private but still accessed from here
result.output1FromB = mandatoryflowBOutput.getOutput1FromB();
}
public FlowCInputBuilder setOptionalflowAOutput(FlowAOutput optionalflowAOutput) {
// same for output2FromA
result.output2FromA = optionalflowAOutput.getOutput2FromA();
return this;
}
#Override
public FlowCInput build() {
return result;
}
}
}
As you see, the builder now holds only a FlowCInput object, it does not unnecessarily hold mandatoryflowBOutput and optionalflowAOutput as before.
I wrote a below Singleton class. I am not sure whether this is thread safe singleton class or not?
public class CassandraAstyanaxConnection {
private static CassandraAstyanaxConnection _instance;
private AstyanaxContext<Keyspace> context;
private Keyspace keyspace;
private ColumnFamily<String, String> emp_cf;
public static synchronized CassandraAstyanaxConnection getInstance() {
if (_instance == null) {
_instance = new CassandraAstyanaxConnection();
}
return _instance;
}
/**
* Creating Cassandra connection using Astyanax client
*
*/
private CassandraAstyanaxConnection() {
context = new AstyanaxContext.Builder()
.forCluster(ModelConstants.CLUSTER)
.forKeyspace(ModelConstants.KEYSPACE)
.withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
.setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE)
)
.withConnectionPoolConfiguration(new ConnectionPoolConfigurationImpl("MyConnectionPool")
.setPort(9160)
.setMaxConnsPerHost(1)
.setSeeds("127.0.0.1:9160")
)
.withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
.setCqlVersion("3.0.0")
.setTargetCassandraVersion("1.2"))
.withConnectionPoolMonitor(new CountingConnectionPoolMonitor())
.buildKeyspace(ThriftFamilyFactory.getInstance());
context.start();
keyspace = context.getEntity();
emp_cf = ColumnFamily.newColumnFamily(
ModelConstants.COLUMN_FAMILY,
StringSerializer.get(),
StringSerializer.get());
}
/**
* returns the keyspace
*
* #return
*/
public Keyspace getKeyspace() {
return keyspace;
}
public ColumnFamily<String, String> getEmp_cf() {
return emp_cf;
}
}
Can anyone help me with this? Any thoughts on my above Singleton class will be of great help.
Updated Code:-
I am trying to incorporate Bohemian suggestion in my code. Here is the updated code, I got-
public class CassandraAstyanaxConnection {
private static class ConnectionHolder {
static final CassandraAstyanaxConnection connection = new CassandraAstyanaxConnection();
}
public static CassandraAstyanaxConnection getInstance() {
return ConnectionHolder.connection;
}
/**
* Creating Cassandra connection using Astyanax client
*
*/
private CassandraAstyanaxConnection() {
context = new AstyanaxContext.Builder()
.forCluster(ModelConstants.CLUSTER)
.forKeyspace(ModelConstants.KEYSPACE)
.withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
.setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE)
)
.withConnectionPoolConfiguration(new ConnectionPoolConfigurationImpl("MyConnectionPool")
.setPort(9160)
.setMaxConnsPerHost(1)
.setSeeds("127.0.0.1:9160")
)
.withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
.setCqlVersion("3.0.0")
.setTargetCassandraVersion("1.2"))
.withConnectionPoolMonitor(new CountingConnectionPoolMonitor())
.buildKeyspace(ThriftFamilyFactory.getInstance());
context.start();
keyspace = context.getEntity();
emp_cf = ColumnFamily.newColumnFamily(
ModelConstants.COLUMN_FAMILY,
StringSerializer.get(),
StringSerializer.get());
}
/**
* returns the keyspace
*
* #return
*/
public Keyspace getKeyspace() {
return keyspace;
}
public ColumnFamily<String, String> getEmp_cf() {
return emp_cf;
}
}
Can anyone take a look and let me know if this time I got it right or not?
Thanks for the help.
You are implementing the lazy initialization pattern - where the instance is created when first used.
But there is a simple trick that allows you to code a threadsafe implementation that doesn't require synchronization! It is known as the Initialization-on-demand holder idiom, and it looks like this:
public class CassandraAstyanaxConnection {
private CassandraAstyanaxConnection(){ }
private static class Holder {
private static final CassandraAstyanaxConnection INSTANCE = new CassandraAstyanaxConnection();
}
public static CassandraAstyanaxConnection getInstance() {
return Holder.INSTANCE;
}
// rest of class omitted
}
This code initializes the instance on the first calling of getInstance(), and importantly doesn't need synchronization because of the contract of the class loader:
the class loader loads classes when they are first accessed (in this case Holder's only access is within the getInstance() method)
when a class is loaded, and before anyone can use it, all static initializers are guaranteed to be executed (that's when Holder's static block fires)
the class loader has its own synchronization built right in that make the above two points guaranteed to be threadsafe
It's a neat little trick that I use whenever I need lazy initialization. You also get the bonus of a final instance, even though it's created lazily. Also note how clean and simple the code is.
Edit: You should set all constructors as private or protected. Setting and empty private constructor will do the work
all above methods are eagerly initializing object. how about this. This will help you to initialize ur class lazily. You may have heavy object and you don't want to initialize on startup.
public class MySinglton {
private MySinglton (){}
private static volatile MySinglton s;
public static MySinglton getInstance(){
if (s != null ) return s;
synchronized(MySinglton.class){
if (s == null ) {
s = new MySinglton();
}
}
return s;
}
}
As mentiond in this great article here :
The best solution to this problem is [...] to use a static field
public class Singelton {
private static final Singelton singleObject = new Singelton();
public Singelton getInstance(){
return singleObject;
}
}
No, its not thread-safe if the values returned on the pulbic methods are changeble objects.
To this class be Thread-safe one way is to change it to be immutable.
To do that, you could change this methods like this:
public Keyspace getKeyspace() {
// make a copy to prevent external user to modified or ensure that Keyspace is immutable, in that case, you don't have to make a copy
return new Keyspace( keyspace );
}
public ColumnFamily<String, String> getEmp_cf() {
// Same principle here. If ColumnFamily is immutable, you don't have to make a copy. If its not, then make a copy
return new ColumnFamily( emp_cf );
}
In this book Java Concurrency in Practice you can see the principle of that immutability.
No, this does not appear to be thread-safe. It appears that you there is mutable data accessible after the call to getInstance, where the lock would have been released.
This should be the correct way to implement Singleton pattern using double checked locking principle:
class MySinglton {
private static volatile MySinglton instance;
private MySinglton() {}
public static MySinglton getInstance() {
if (instance == null) {
synchronized (MySinglton.class) {
if (instance == null) {
instance = new MySinglton();
}
}
}
return instance;
}
}
I think this will do the same thing without having to check for instance every time. static is the same as check first time
public class Singl {
private static Singl _instance;
//other vars
static{
//synchronized(Singl.class){//do not need
_instance = new Singl();
//}
}
public static Singl getInstance() {
return _instance;
}
private Singl(){
//initizlize
}
}
After java 1.5 version we can use volatile. If we used volatile java key ward, we can create singlton class with thread safe, Because instance variable share with Other thread as well.
public class SingleWithThreadSafe {
// create an object static referance of SingleWithThreadSafe with volatile
private static volatile SingleWithThreadSafe instance = null;
// if we make the constructor private so that this class cannot be
// instantiated from out side of class
private SingleWithThreadSafe() {
}
// Get only object available
public static SingleWithThreadSafe getInstance() {
if (instance == null) {
instance = new SingleWithThreadSafe();
}
return instance;
}
public void showMessage() {
System.out.println("Hello World!");
}
}
I come from writing a lot of JavaScript, so bear with me.
I've got 3 HashMaps, which i reference in a method in a different class. My code (very simply) looks like so:
public class MainClass {
private HashMap<String,Nation> randomHashMap = new HashMap<String,Nation>();
DifferentClass d = new DifferentClass(this);
} //with getters/setters
public class DifferentClass {
private MainClass mc;
public void randomMethod() {
System.out.println("randomHashMap is " + (mc.getRandomHashMap() == null));
} //returns null
public DifferentClass(MainClass c) {
this.mc = c;
}
}
However, when I call them in my other method, they're null.
How do I create a new, empty HashMap?
You need to initialize your MainClass mc variable before using it in the DifferentClass#randomMethod method. Also, make sure you're using the mc variable instead of the MainClass.getRandomHashMap() method (by your actual code, we don't know how it behaves). Your code will look like this:
public class DifferentClass {
private MainClass mc = new MainClass();
public void randomMethod() {
//assuming getRandomHashMap is the getter of randomHashMap attribute (and non static)
System.out.println("randomHashMap is " + (mc.getRandomHashMap() == null));
}
}
public class MainClass {
private HashMap<String,Nation> randomHashMap = new HashMap<String,Nation>();
DifferentClass d = new DifferentClass(this);
public HashMap<String,Nation> getRandomHashMap() {
return this.randomHashMap;
}
} //with getters/setters
The code you posted is in fact perfectly all right as far as field initialization. I made an SSCCE from it with minimal intervention:
class Nation{}
public class MainClass {
private HashMap<String,Nation> randomHashMap = new HashMap<String,Nation>();
DifferentClass d = new DifferentClass(this);
public Object getRandomHashMap() {
return randomHashMap;
}
public static void main(String[] args) {
new MainClass().d.randomMethod();
}
} //with getters/setters
class DifferentClass {
private MainClass mc;
public void randomMethod() {
System.out.println("randomHashMap is " + (mc.getRandomHashMap() == null));
} //returns null
public DifferentClass(MainClass c) {
this.mc = c;
}
}
and it prints
randomHashMap is false
which proves that randomHashMap is indeed non-null.