I have a java private method and I am trying to find the best way to create an object inside the method. Following are two different approaches that I am trying:
Approach A:
private void createObject() {
Object A;
if (conditionA) {
A = new Object();
//do some Action X with object A
} else {
//Do something without object A
if (conditionB) {
return;
}
A = new Object();
//do some Action Y with object A
}
return;
}
Approach B:
private void createObject() {
Object A = new Object()
if (conditionA) {
//do some action X with Object A
} else {
//Do something without Object A
if (conditionB) {
return;
}
//do some action Y with Object A
}
return;
}
Obviously both the code snippets are working and without any issues. I am just trying to find out the better coding style and standard.
Let's write the truth table
A | B | Expected Outcome
-----+-------+-------------------------------
True | True | do X with object A
True | False | do X with object A
False| False | do Y with object A
False| True | do something without object A
-----+-------+-------------------------------
I think this translates to:
boolean doXWithA = conditionA;
boolean doYWithA = !conditionA && !conditionB;
boolean doSomethingWithA = doXWithA || doYWithA;
if(doSomethingWithA)
Object a = new Object();
if (doXWithA) {
// do X with object A
} else if (doXWithB) {
// do X with object B
}
} else {
// do something without object A
}
Good practice is to reduce the scope of variables as much as possible. And if the instantiation is expensive, you also want to reduce the number of time you instantiate it.
Here Object a is only initialised when necessary and its scope is as small as possible (only one if block)
I believe that if you want to initialize object with default value you should do this in the place of declaration
Object A = new Object();
if (conditionA) {
...
}
Approach A is better.
In that, Consider "if" condition is not satisfied and it goes in "else".
There if conditionB is satisfied, then it will return.So memory is not allocated to A.
In Approach B, unnecessarily memory allocation is done which is of no use in above scenario.
I would go with approach A, as it is only necessary to initialize the object when needed.
If the initialization of that object is rather complicated, in order to avoid repeating yourself, you either define a static helper method in order to initialize the object or you go via a Supplier<>:
Supplier<Type> objSupplier = () -> new Type(a, b, c, d, whatever)
and then, at the two places where the object is supposed to be created, you do
A = objSupplier.get();
(note that variables are usually written in lowercase/camelCase).
Related
I have a situation where I need to give an error message when someone tries to delete an object b from a bList and it is used in some other class say class A.
If b is not referenced in another class then I should not throw an error message.
Pseudo code for the above scenario
public class A {
B b;
void setB(B b) {
this.b = b;
}
}
public class NotifyTest {
List<B> bList = new ArrayList<>();
String notifyTest() {
A a = new A();
B b = new B();
a.setB(b);
bList.add(b);
if (b referencedSomewhere)
{
return "error";
}
else
{
bList.remove(b);
return "success";
}
}
}
Traversing my entire model to check if object b is used somewhere is a performance hit so I don't want to go for that approach.
Please let me know if there is any solution for this scenario provided by Java or suggest a better way to handle this.
Edit1 : I need an error message when b is referenced in any other place other than bList
If your intention here is to automatically free up items from the list that are no longer referenced you can use https://docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html
You could also use this to keep track of all keys that are not yet garbage collected. This can provide you the information about which items are already garbage collected (after becoming unreachable). However, the information won't be realtime as the garbage collector may run at arbitrary times.
I think something like the following should work for you. This is quickly put together to show you the idea. It has not been tested and will need more work if you want it to be thread safe.
class RefCounter<T>
{
private HashMap<T, Integer> counts = new HashMap<>();
public T using(T object)
{
Integer num = counts.get(object);
if (num == null)
counts.put(object, 1);
else
counts.put(object, num+1);
return object;
}
public T release(T object)
{
Integer num = counts.get(object);
if (num == null)
throw new IllegalArgumentException("Object not in RefCounter");
else if (num == 1)
counts.remove(object);
else
counts.put(object, num-1);
return object;
}
public boolean usedElsewhere(T object)
{
Integer num = counts.get(object);
return (num != null && num > 1);
}
}
When you use an object, add it to RefCounter.
refCounter.using(x);
someList.add(x);
When you are done with that object
someList.remove(index);
refCounter.release(x);
To test if the object is used elsewhere
if (refCounter.usedElsewhere(x) {
return "error";
} else {
someList.remove(index);
refCounter.release(x);
}
Remember you'll need to ensure you call using() and release() every time you keep or release an object, otherwise this is all pointless.
If the object is absolutely not used (or there's not much memory left) then java will mark it deleted, then when you start using up your memory, java will automatically do the garbage collection for you.
Most of the high level have garbage collection (GC), like java, C#, Python (iirc), etc. You only need to keep attention on memory if you use more low level languages, like C ir C++ (wich is somewhere between low and high level actually)
I am well aware that it is not good practice to synchronize on Boolean.
There is a lot explanation why it's not good such as:
Why is it not a good practice to synchronize on Boolean?
http://telliott.io/node/40/
https://www.securecoding.cert.org/confluence/display/java/LCK01-J.+Do+not+synchronize+on+objects+that+may+be+reused
etc.
So, it is clear that this is BAD practice:
The code synchronizes on a boxed primitive constant, such as an
Boolean.
private static Boolean inited = Boolean.FALSE;
...
synchronized(inited)
{
if (!inited)
{
init();
inited = Boolean.TRUE;
}
}
...
What interests me is what happens if we create final static Boolean with "new" operator, i.e. someting like this (this is from real code I haven't wrote but I maintain it, names of methods etc. are changed):
private final static Boolean lock = new Boolean(true);
...
public static SomethingGeneric getSomething()
{
synchronized(lock)
{
if (somethingElse == null)
{
try
{
somethingElse = persistence.valueobject.getSomeValue(GET_THAT);
System.out.println("blah blah");
}
catch (ObjectCreationException oce)
{
// report the error
log.error("There was this and that error", oce);
System.out.println("Could not create it");
}
}
return somethingElse;
}
}
Would it be then "legal" to use it? Same as if we used Object such as in:
private final Object lock = new Object();
or
private static final Object lock = new Object();
public void doSomething() {
synchronized (lock) {
// ...
}
}
Thats fine. There are two problems with your first snippet, not that it is a Boolean but first, the object changes in this line:
inited = Boolean.TRUE;
So some threads can be synchronized on the old object and some on the new. This means, there is no synchronization between the two groups.
And second, Boolean.TRUE and Boolean.FALSE are global objects and if they are used in a similar way somewhere else this will create some hard to detect synchronisation problems (thanks to Mark Rotteveel for pointing it out).
You are synchronizing on the object reference. Creating private final Object lock = new Object(); would have the same effect as private final static Boolean lock = new Boolean(true);. All you want in this case is a unique object.
You should be careful though, because new Boolean(true) will create a new object reference. If you tried to use Boolean.TRUE or true they are in essence interned and will use the same instance, for example:
Boolean bool1 = new Boolean(true);
Boolean bool2 = Boolean.TRUE;
Boolean bool3 = true;
System.out.println(System.identityHashCode(bool1));
System.out.println(System.identityHashCode(bool2));
System.out.println(System.identityHashCode(bool3));
Will print
1433743869
19203296
19203296
So synchronizing on bool1 will be mutually exclusive to bool2 and bool3 but 2 & 3 will share exclusivity.
Note identityHashCode will give you the reference hash code, that tells you which objects are == equal.
Since new Boolean(true) != new Boolean(true), you can use such a lock.
Be careful though since Boolean.valueOf(true) == Boolean.valueOf(true).
All together if you are maintaining that code, just replace the lock with lock = new Object() as you suggest.
Since new Boolean(...) gives you a brand-new Object, the only difference between using new Boolean(...) and new Object() for your lock would be the fact that Boolean has a true or false value associated with it, while Object does not.
You can check that you get new objects from calling new Boolean(...) by running this code snippet:
Boolean bt = Boolean.TRUE;
Boolean bf = Boolean.FALSE;
for (int i = 0 ; i != 20 ; i++) {
Boolean b = new Boolean(i % 2 == 0);
System.out.println(b);
System.out.println("==true : "+(b==bt));
System.out.println("==false: "+(b==bf));
}
This prints
true
==true : false
==false: false
false
==true : false
==false: false
true
==true : false
==false: false
false
==true : false
==false: false
...
meaning that the objects you get are not the same as Boolean.TRUE and Boolean.FALSE.
Note: Although the practice appears completely harmless, I see no point in trying to synchronize on a Boolean, an Integer, a String, or any other immutable object, because it gives you no advantages over synchronizing on Object lock = new Object(), while not being as recognizable an idiom. This reflects on readability of your code, because programmers reading your code would be scratching their heads over your decision to lock on new Boolean(...).
I was recently asked a question that stumped me.
public void swapEngine(Car a, Car b) {
Engine temp = a.engine;
a.engine = b.engine;
b.engine = temp;
}
This is not a thread-safe method. If Thread 1 calls swapEngine(car1, car2) and then Thread 2 calls swapEngine(car1, car3), it is possible for car2 to end up with the engine of car3. The most obvious way to fix this problem is to synchronize the method.
Synchronizing the method introduces a potential inefficiency. What if Thread 1 calls swapEngine(car1, car2) and Thread 2 calls swapEngine(car3, car4)? In no way can these two threads interfere with each other. In this case the ideal situation would be for the two threads to swap the engines in parallel. Synchronizing the method precludes this from happening.
Is there another technique to swap these engines in a thread-safe manner while still taking advantage of parallelism?
Edit: Made method public.
As the comments say, you can lock the cars themselves. This, however could cause a deadlock if cars are not always locked in the same order.
So, if cars have a unique identifier, you can simply sort the cars, and then swap:
void swapEngine(Car a, Car b) {
Comparator<Car> byId = Comparator.comparing(Car::id);
Car[] cars = new Car[] {a, b};
Arrays.sort(cars, byId);
doSwap(cars[0]), cars[1];
}
private void doSwap(Car a, Car b) {
synchronized(a) {
synchronized(b) {
Engine temp = a.engine;
a.engine = b.engine;
b.engine = temp;
}
}
}
If the cars don't have any unique ID allowing to compare them, you can sort them by their identity hashCode (obtained using System.identityHashCode(car)). This hashCode, unless you have a huge memory, an enormous amount of cars, and bad luck, is unique. If you really fear such a situation, then Guava has an arbitrary ordering that you can use.
If you store Car.engine in AtomicReference, you could swap them using the CAS operations:
public <T> void atomicSwap(AtomicReference<T> a, AtomicReference<T> b) {
for(;;) {
T aa = a.getAndSet(null);
if (aa != null) {
T bb = b.getAndSet(null);
if (bb != null) {
// this piece will be reached ONLY if BOTH `a` and `b`
// contained non-null (and now contain null)
a.set(bb);
b.set(aa);
return;
} else {
// if `b` contained null, try to restore old value of `a`
// to avoid deadlocking
a.compareAndSet(null, aa);
}
}
}
}
Advantage of this approach is that it doesn't require right object ordering and don't use intrinsic locks. It also doesn't need to lock on full object--other properties can be manipulated in parallel.
Disadvantage is that now null values are illegal: they mean that operation on variable is in progress. You'll need to check for null when getting values and setting them anywhere but in constructor:
public <T> T getValue(AtomicReference<T> a) {
for(;;) {
T v = a.get();
if (v != null)
return v;
}
}
public <T> T setValue(AtomicReference<T> a, T value) {
for(;;) {
T old = a.get();
if (old != null && a.compareAndSet(old, value))
return old;
}
}
Say I have objects A,B,C,D. They can contain references to one another, for example, A might reference B and C, and C might reference A. I want to create segments but dont want to create them twice, so I don't want segment A C and segment C A, just 1 of them. So I want to keep a list of created segments, ex: A C, and check if I already have an A C or C A and skip it if so.
Is there a data structure that can do this?
Thanks
if(list.contains(a,b)
{
//dont add
}
you may introduce something like
class PairKey<T extends Comparable<T>> {
final T fst, snd;
public PairKey(T a, T b) {
if (a.compareTo(b) <=0 ) {
fst = a;
snd = b;
} else {
fst = b;
snd = a;
}
}
#Override
public int hashCode() {
return a.hashCode() & 37 & b.hashCode();
}
#Override
public boolean equals(Object other) {
if (other == this) return true;
if (!(other instanceOf PairKey)) return false;
PairKey<T> obj = (PairKey<T>) other;
return (obj.fst.equals(fst) && obj.snd.equals(snd));
}
}
then you may put edges into HashSet < PairKey < ? extends Comparable> > and then check if the given pair is already there.
You will need to make your vertexes comparable, so it will be possible to treat PairKey(A,B) equal to PairKey(B,A)
And then HashSet will do the rest for you, e.g you will be able to query
pairs.contains(new PairKey(A,B));
and if pairs contain either PairKey(A,B) or PairKey(B,A) - it will return true.
hashCode implementation might be slightly different, may be IDE will generate something more sophisticated.
Hope that helps.
I would use an object called Pair that would look something like this:
class Pair
{
Node start;
Node end;
public Pair(Node start, Node end)
{
this.start=start;
this.end=end;
}
public Pair reverse()
{
return new Pair(end,start);
}
}
Now you can do something like this:
if(pairs.contains(currentPair) || pairs.contains(currentPair.reverse())
{
continue;
} else{
pairs.add(currentPair);
}
As pointed out in the comments, you will need to implement equals and hashcode. However, doing the check in equals to make it match the reversal of the segment is a bad practice in a pure OO since. By implementing equals in the fashion, described within the comments, would bind Pair to your application only and remove the portability of it.
You can use a set of sets of objects.
Set<Set<MyObjectType>> segments = new HashSet<Set<MyObjectType>>();
Then you can add two-element sets representing pairs of MyObject. Since sets are unordered, if segments contains a set with A and B, attempting to add a set containing B and A will treat it as already present in segments.
Set<MyObjectType> segment = new HashSet<MyObjectType>();
segment.add(A); // A and B are instances of MyObjectType
segment.add(B);
segments.add(segment);
segment = new HashSet<MyObjectType>();
segment.add(B);
segment.add(A);
segments.add(segment);
System.out.println("Number of segments: " + segments.size()); // prints 1
Your problem is related with graph theory.
What you can try is to remove that internal list and create a Incidence Martrix, that all you objects share.
The final solution mostly depend of the task goal and available structure. So is hard to choose best solution for you problem with the description you have provided.
Use java.util.Set/ java.util.HashSet and keep adding the references you find e.g.
Set set1 = new HashSet();
set1.add(A), set1.Add(C), set1.Add(C)
You can add this finding in an external set, as finalSet.add(set1)
Set<Set> finalSet = new HashSet<Set>();
finalSet.add(set1);
This will filter out the duplicates automatically and in the end, you will be left with A & C only.
I have game objects in an array collection, but they can be different classes. I can find the object by its coordinates:
Object obb = grid.getCellContent(insertObjectX, insertObjectY);
What I need to do is to find if obb.canBeSubmerged == true and then simply move it to another array.
The problem is that I canot get a property of that object "canBeSubmerged" because compilier does not know which class I used.
I wonder if there is a quicker way to do it then to go through "obb.getClass() == myClass.class" statements for each of the possible object classes.
.
.
EDIT: based on stuckless suggestion here is a working solution:
try {
java.lang.reflect.Field f1 = obb.getClass().getField("canBeSubmerged");
java.lang.reflect.Field f2 = obb.getClass().getField("subObject");
if (f1 != null) {
canBeSubmerged = f1.getBoolean(obb);
f2.setBoolean(obb, canBeSubmerged);
}
}catch (Exception e) { }
//enter it into the submerged grid level and remove from the top grid level
if (canBeSubmerged){
grid.removeObject(insertObjectX, insertObjectY);
grid.putSubObjectInCell(insertObjectX, insertObjectY, obb);
}
If your obb object that contains the canBeSubmerged property is always of a particular class type, such as MyOBB.class, then you can do this...
if (obb instanceof MyOBB.class) {
if (((MyOBB)obb).canBeSubmerged) {
// do your work
}
}
========= OR ============
Using Reflection (which will be slower)
try {
Field f = obb.getClass().getField("canBeSubmerged");
if (f!=null && f.getBoolean(obb)) {
// do your work
}
} catch (Exception e) {
}
Your objects should probably all extend a common superclass or implement a common interface which defines a method
public boolean canBeSubmerged();
You should not use public fields. And also note that
if (obb.canBeSubmerged() == true)
can be written as
if (obb.canBeSubmerged())
which is more logical and readable.
If you are only interested in one attribute of the object your could extract that to an interface
public interface Submergable {
boolean isSubmerged();
}
And let all objects that may submerge implement it.
Then you can do Object instanceof Submergable