If i have an immutable class like this:
public class MathClass {
private final int x;
public MathClass(int x) {
this.x = x;
}
public int calculateSomething() {
return Math.sqrt(x);
}
}
Does the jvm cache the result of calculateSomething() on the first call?
I have a more complicated calculation in the MathClass.
No it does not, only the object is stored within the cache
You could use your own caching solution, such as Spring's #Cacheable to store method results in cache
No, Java doesn't cache method results in general.
Some few methods of the Framework do this, but it's part of their implementation, e.g. Integer.valueOf(int).
c.f. JavaDoc:
This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range."
But with your implementation it would be easy to implement the "caching" by yourself: the class is immutable, that means the inputs don't change, so you can easily calculate the value on the first request and return the previously calculated value on subsequent requests:
public class MathClass {
private final int x;
private transient boolean calculated = false;
private transient int preCalcSomething;
public MathClass(int x) {
this.x = x;
}
public int calculateSomething() {
if (!calculated) {
preCalcSomething = Math.sqrt(x);
calculated = true;
}
return preCalcSomething;
}
}
I used the transient keyword here to mark that those two fields are not part of the "object state". Don't forget to exclude them from equals and hashCode calculations and maybe other state-depending methods!
If you are using an object instead of a primitive, I would use null as indicator for "not yet calculated" if that is a value that cannot be the actual result of the cached operation.
You could calculate it just once, and then return the result previously calculated.
public class MathClass {
private final int x;
private final int result;
public MathClass(int x) {
this.x = x;
this.result = Math.sqrt(x);
}
public int calculateSomething() {
return result;
}
}
The calculation will not be performed more than one time. This is not a cache but works as one in your scenario.
Related
I'm writing a program that will need to use a limited set of Points to process an image. I figure that I would implement it as an immutable/singleton style class. Before going on to build more of the complex logic surrounding the class I wanted to get an opinion about the core class.
import org.apache.commons.lang3.builder.HashCodeBuilder;
import java.util.HashMap;
public class Point {
private final int x,y;
private final int hashCode;
private static final HashMap<int[],Point> points = new HashMap<>();
private Point(int x,int y){
this.x = x;
this.y = y;
this.hashCode = new HashCodeBuilder().append(x).append(y).toHashCode();
}
public static Point getPoint(int x,int y){
int [] candidate = new int[]{x,y};
if(points.containsKey((candidate))){
return points.get(candidate);
}
Point newPoint = new Point(x,y);
points.put(candidate, newPoint);
return newPoint;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
#Override
public int hashCode(){
return hashCode;
}
#Override
public boolean equals(Object p){
return this == p;
}
}
I'm going to be using the class to do at least the following functions:
Map different channels in an image by this Point class
Define some static cached custom NavigableSets for ease of traversal
Various Helper functions. In example, get all Points surrounding a Point
Given the information provided, what are some downsides of the provided implementation?
Note: Putting the bulleted list before the code block breaks the display of the code block. Bug?
I think your caching "singletony" stuff may be pointless.
It doesn't save on object creation, as you will always create a candidate[] each time you ask for a Point. And, unless the Point gets reused, you use the memory for candidate and the Map.Entry in your HashMap. So, very roughly speaking, unless each Point gets reused three times, your caching uses more memory. And it always uses a more time.
If you don't cache, change your equals of course.
p.s. the rest seems fine, and immutable is good. You could consider making x and y public final to be more compatible with other Point implementations.
If you are worried about the occupied memory, there is another way to deal with it.
I assuming you have limited dimension for your points, I would suggest to combine your x & y in one variable of long (in case your dimensions is 32 ints long), or even int (if you can fit one dimensions in 16 bit), this way you'll get boost in performance & memory.
Other option is to use int[] array of your coordinates for a point, although that would take more space (since you would have to keep additional pointer reference).
Factory method in your implementation, will work only on single threaded applications, if you have multiple threads creating points, you would need to have some concurrency control in place. This would eat up your resources, because you would effectively need to lock on each point creation.
Another reason, why this Factory method is a bad idea, is that int[] arrays do not override equals and hashCode, you can try to create 2 arrays with same content, to check. So your HashMap would not simply work, and instead of saving memory you would not only create a new Point each time, but also add an entry to your HashMap and perform unnecessary calculations.
So either use Java primitives, or just create a new immutable Point each time if you need too, and go with it, don't overcomplicate with factoryMethods.
You had the right idea of making the Point class immutable but then you went and complicated things with the instance cache. It is not thread safe and it will leak memory because once a Point is created it will forever stay in the hashmap and will never be garbage collected.
Why not keep it simple and make a regular boring value class? Your IDE will even generate it for you.
Then, if you really really really want to have an instance cache, use Guava's Interner class instead of rolling your own. The result will look something like this:
public class Point {
final int x;
final int y;
private Point(int x, int y) {
this.x = x;
this.y = y;
}
static Interner<Point> instanceCache = Interners.newWeakInterner();
public static Point of(int x, int y) {
return instanceCache.intern(new Point(x,y));
}
public int getX() { return x; }
public int getY() { return y; }
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Point other = (Point) o;
return this.x == other.x && this.y == other.y;
}
#Override
public int hashCode() { return x * 31 + y; }
}
This is more of a logical question than code specific, I have some twenty functions, each function calculates two values of my interest. However I can only return one value from a function. Now the other option I have is to make a class and implement setter and getter with global variables. I want to know if this is a feasible and recommended way? Or there is a better way to do this?
Don't use global variables! Use some class that has your data as private fileds, and provide getters for it. Like in
class Pair<A,B> {
final A one;
final B two;
public Pair(A fst, B snd) { one = fst; two = snd; }
public A getFst() { return one; }
public B getSnd() { return two; }
}
Then you can elsewhere say something like:
return new Pair(42, "a result");
Return a Collection from your function containing your values of interest.
Depends on the problem. But 2 solutions are :
Make new class which instances will be returned by all this functions. This class would have 2 attributes for each needed answer.
Return array or Collection with this 2 answers.
You have to return a List or a array.
But if return types are different you can create custom class and use it as return type.
Example
public class Result {
private String name;
private int age;
// getters and setters;
}
Now you can have some thing like following
public static Result getInfo(){
Result result=new Result();
result.setName("name");
result.setAge(10);
return result;//now you can have String and int values return from the method
}
There are many ways: collections, arrays ...
In my opinion the only way is to define a class with these values.
you do not need getter and setter methods if you don't need to regulate the visibility of the contents
class MyReturnValue {
public int a;
public int b;
}
in your code:
...
MyReturnValue result=new MyReturnValue();
result.a=5;
result.b=6;
return result;
It is better to make a class and implement setter and getter with global variables rather than to Return Collection further it depends on your use.
You can do this
long[] function() {
long[] ret = { a, b };
return ret;
}
or
long[] a = { 0 }, b = { 0 };
void function(long[] a, long[] b) {
a[0] = ...
b[0] = ...
or add properties to an object.
private long a,b;
void function() {
a = ...
b = ...
}
in the last case you can value.
class Results {
public final long a;
public final Date b; // note: Date is not immutable.
// add constructor
}
public Results function() {
long a = ...
Date b = ...
return new Results(a, b);
}
I think making a Record class is the most suitable.
public class Record {
public final int a;
public final int b;
public Record(final int a, final int b) {
this.a = a;
this.b = b;
}
}
Then your functions can return type Record, and you can access it with let's say record.a and record.b.
This is also one of the few cases where public variables and no getters and setters can be justified.
UPDATE: Implemented a proposed change, now everything is final, which means that Record cannot be modified when you get it back, which seems to be in line with expectations. You only want the results and use those.
What about adopting varargs with generic helper function for getting around of number of returning variable limitation: In this solution, we won't have to declare a new class every time when number of returning variable changes.
class Results
{
private final Object[] returnedObj;
public Results(Object... returnedObj)
{
this.returnedObj = returnedObj;
}
public <E> E getResult(int index)
{
return (E)returnedObj[index];
}
}
Test case:
public static Results Test()
{
return new Results(12, "ABCD EFG", 12.45);
// or return larger number of value
}
//// And then returning the result
Results result = Test();
String x = result.<String>getResult(1);
System.out.println(x); // prints "ABCD EFG"
You could even return the values separated by a special character say a "~" if you are sure that the "~" won't appear in your results.
I realize that if I pass an object as a parameter of a function and do changes to it, the changes "stay" with the object. But it is not the case for an integer.
public void start() {
int x = 100;
modify(x);
// I would like x to be 200 now. But it isn't :(
}
public void modify(int y) {
y *= 2;
}
So basically, is there a way to achieve what I wanted in the code above? Is it possible to modify an integer like that (like an object reference)?
While working with primitives there is no concept of "reference". But you may achieve what you want by doing something like below:
x = modify(x); may be code want.
Now x contains the results of modify(x) method invocation.
You cannot do that. Primitives are passed by value. (References are also passed by value. You can't modify an object reference; you can only modify the object that is referenced.) The best you can do is:
public void start() {
int [] x = {100};
modify(x);
// x[0] is now 200 :)
}
public void modify(int []y) {
y[0] *= 2;
}
The array reference x is passed by value, but you can modify the array elements. Note that passing an Integer won't help, because Integer objects are immutable.
Alternatively, you can redesign your method to return the doubled value and assign it in the calling code (as Nambari suggests).
A third possibility, beside passing an array or using a return value, would be to pass an object of some ValueHolder class with a getter and setter:
public class IntValueHolder
{
private int value;
public int getValue()
{
return this.value;
}
public void setValue(final int value)
{
this.value = value;
}
}
This is technically very similar to passing an array, but is IMHO a bit cleaner, i.e. it better describes your intent.
One thing you can do is get the return value of the modify() method and assign it to the variable as follows.
public void start() {
int x = 100;
x=modify(x);
}
public int modify(int y) {
return y *= 2;
}
I am reading the book Effective Java.
In an item Minimize Mutability , Joshua Bloch talks about making a class immutable.
Don’t provide any methods that modify the object’s state -- this is fine.
Ensure that the class can’t be extended. - Do we really need to do this?
Make all fields final - Do we really need to do this?
For example let's assume I have an immutable class,
class A{
private int a;
public A(int a){
this.a =a ;
}
public int getA(){
return a;
}
}
How can a class which extends from A , compromise A's immutability ?
Like this:
public class B extends A {
private int b;
public B() {
super(0);
}
#Override
public int getA() {
return b++;
}
}
Technically, you're not modifying the fields inherited from A, but in an immutable object, repeated invocations of the same getter are of course expected to produce the same number, which is not the case here.
Of course, if you stick to rule #1, you're not allowed to create this override. However, you cannot be certain that other people will obey that rule. If one of your methods takes an A as a parameter and calls getA() on it, someone else may create the class B as above and pass an instance of it to your method; then, your method will, without knowing it, modify the object.
The Liskov substitution principle says that sub-classes can be used anywhere that a super class is. From the point of view of clients, the child IS-A parent.
So if you override a method in a child and make it mutable you're violating the contract with any client of the parent that expects it to be immutable.
If you declare a field final, there's more to it than make it a compile-time error to try to modify the field or leave it uninitialized.
In multithreaded code, if you share instances of your class A with data races (that is, without any kind of synchronization, i.e. by storing it in a globally available location such as a static field), it is possible that some threads will see the value of getA() change!
Final fields are guaranteed (by the JVM specs) to have its values visible to all threads after the constructor finishes, even without synchronization.
Consider these two classes:
final class A {
private final int x;
A(int x) { this.x = x; }
public getX() { return x; }
}
final class B {
private int x;
B(int x) { this.x = x; }
public getX() { return x; }
}
Both A and B are immutable, in the sense that you cannot modify the value of the field x after initialization (let's forget about reflection). The only difference is that the field x is marked final in A. You will soon realize the huge implications of this tiny difference.
Now consider the following code:
class Main {
static A a = null;
static B b = null;
public static void main(String[] args) {
new Thread(new Runnable() { void run() { try {
while (a == null) Thread.sleep(50);
System.out.println(a.getX()); } catch (Throwable t) {}
}}).start()
new Thread(new Runnable() { void run() { try {
while (b == null) Thread.sleep(50);
System.out.println(b.getX()); } catch (Throwable t) {}
}}).start()
a = new A(1); b = new B(1);
}
}
Suppose both threads happen to see that the fields they are watching are not null after the main thread has set them (note that, although this supposition might look trivial, it is not guaranteed by the JVM!).
In this case, we can be sure that the thread that watches a will print the value 1, because its x field is final -- so, after the constructor has finished, it is guaranteed that all threads that see the object will see the correct values for x.
However, we cannot be sure about what the other thread will do. The specs can only guarantee that it will print either 0 or 1. Since the field is not final, and we did not use any kind of synchronization (synchronized or volatile), the thread might see the field uninitialized and print 0! The other possibility is that it actually sees the field initialized, and prints 1. It cannot print any other value.
Also, what might happen is that, if you keep reading and printing the value of getX() of b, it could start printing 1 after a while of printing 0! In this case, it is clear why immutable objects must have its fields final: from the point of view of the second thread, b has changed, even if it is supposed to be immutable by not providing setters!
If you want to guarantee that the second thread will see the correct value for x without making the field final, you could declare the field that holds the instance of B volatile:
class Main {
// ...
volatile static B b;
// ...
}
The other possibility is to synchronize when setting and when reading the field, either by modifying the class B:
final class B {
private int x;
private synchronized setX(int x) { this.x = x; }
public synchronized getX() { return x; }
B(int x) { setX(x); }
}
or by modifying the code of Main, adding synchronization to when the field b is read and when it is written -- note that both operations must synchronize on the same object!
As you can see, the most elegant, reliable and performant solution is to make the field x final.
As a final note, it is not absolutely necessary for immutable, thread-safe classes to have all their fields final. However, these classes (thread-safe, immutable, containing non-final fields) must be designed with extreme care, and should be left for experts.
An example of this is the class java.lang.String. It has a private int hash; field, which is not final, and is used as a cache for the hashCode():
private int hash;
public int hashCode() {
int h = hash;
int len = count;
if (h == 0 && len > 0) {
int off = offset;
char val[] = value;
for (int i = 0; i < len; i++)
h = 31*h + val[off++];
hash = h;
}
return h;
}
As you can see, the hashCode() method first reads the (non-final) field hash. If it is uninitialized (ie, if it is 0), it will recalculate its value, and set it. For the thread that has calculated the hash code and written to the field, it will keep that value forever.
However, other threads might still see 0 for the field, even after a thread has set it to something else. In this case, these other threads will recalculate the hash, and obtain exactly the same value, then set it.
Here, what justifies the immutability and thread-safety of the class is that every thread will obtain exactly the same value for hashCode(), even if it is cached in a non-final field, because it will get recalculated and the exact same value will be obtained.
All this reasoning is very subtle, and this is why it is recommended that all fields are marked final on immutable, thread-safe classes.
If the class is extended then the derived class may not be immutable.
If your class is immutable, then all fields will not be modified after creation. The final keyword will enforce this and make it obvious to future maintainers.
Adding this answer to point to the exact section of the JVM spec that mentions why member variables need to be final in order to be thread-safe in an immutable class. Here's the example used in the spec, which I think is very clear:
class FinalFieldExample {
final int x;
int y;
static FinalFieldExample f;
public FinalFieldExample() {
x = 3;
y = 4;
}
static void writer() {
f = new FinalFieldExample();
}
static void reader() {
if (f != null) {
int i = f.x; // guaranteed to see 3
int j = f.y; // could see 0
}
}
}
Again, from the spec:
The class FinalFieldExample has a final int field x and a non-final int field y. One thread might execute the method writer and another might execute the method reader.
Because the writer method writes f after the object's constructor finishes, the reader method will be guaranteed to see the properly initialized value for f.x: it will read the value 3. However, f.y is not final; the reader method is therefore not guaranteed to see the value 4 for it.
I am trying to convert these small math calls to Java from C# and just wanted to make sure that they operate the same way. I added one additional call as it is not supported in Java.
Here is code in C#
public override int CompareTo(object a)
{
EquationGenome Gene1 = this;
EquationGenome Gene2 = (EquationGenome)a;
return Math.Sign(Gene2.CurrentFitness - Gene1.CurrentFitness);
}
Java:
Notice the Math.Sign is not being called.
/**
* Compare to.
*/
public int compareTo(final Object a) {
final EquationGenome gene1 = this;
final EquationGenome gene2 = (EquationGenome) a;
return (int) ((-1.0) * (gene2.currentFitness - gene1.currentFitness));
}
And here is one to replicate C#'s 'next' with two int parameters in Java:
public static final int nextInt(final Random r, final int min, final int max) {
final int diff = max - min;
final int n = r.nextInt(diff);
return n + min;
}
Are these methods equivalent from C# to Java?
Why not just use Java's compareTo? This is assuming currentFitness is of type Integer and not the primitive type int. Otherwise you can just wrap it in Integer. This is not the most efficient method but it's more clear to me.
/**
* Compare to.
*/
public int compareTo(final Object a) {
final EquationGenome gene1 = this;
final EquationGenome gene2 = (EquationGenome) a;
return gene1.currentFitness.compareTo(gene2.currentFitness);
}
No, because Math.Sign in C# returns one of three values: -1 if the value is < 0, 0 if the value is equal to 0, and 1 if the value is greater than 0. It doesn't flip the sign by multiplying by -1 as you're doing in the Java code.
In C# the CompareTo function expects -1 to mean that the object on which it is called is less than the object being passed in. Since you're returning the sign of subtracting value 1 from value 2, this will be switched. I doubt this is what you want for your algorithm, given your Java code. Traditionally you would subtract value 2 from value 1 and use that sign.
If your Java version of EquationGenome implements the Comparable interface, you'll be able to take advantage of many Java APIs. This would alter your class to look like this:
final class EquationGenome
implements Comparable<EquationGenome>
{
...
public int compareTo(final EquationGenome gene2) ...
Then, what you are doing with the multiplication isn't clear. I assume the "natural order" is from most fit to least fit. Then I'd implement the comparison like this:
public int compareTo(final EquationGenome that) {
if (currentFitness == that.currentFitness) {
/* TODO: Add more tests if there are other properties that distinguish
* one EquationGenome from another (secondary sort keys). */
return 0;
} else
return (currentFitness > that.currentFitness) ? -1 : +1;
}
By convention, you should either implement the equals method to be "consistent" with your compareTo method, or clearly document your class to note the inconsistency. If you implement equals, you should also implement hashCode for consistency too.
public boolean equals(Object o) {
return o instanceof EquationGenome && compareTo((EquationGenome) o) == 0;
}
public int hashCode() {
return currentFitness;
}
The method for producing random numbers is alright, as long as you understand that max is excluded; the method generates random numbers from the half-open interval (min, max]. If you want to include max in the range, add one to diff.
I would write something like.
Note: You have be very careful using Comparator with mutable fields as this can have undesirable side effects.
public class EquationGenome implenents Comparable<EquationGenome> {
private final double currentFitness;
public EquationGenome(double currentFitness) {
this.currentFitness = currentFitness;
}
public int compareTo(EquationGenome eg) {
return Double.compareTo(currentFitness, eg.currentFitness);
}
}