What is the difference between these two methods - java

These two methods calculate the derivative of a monom, but I dont understand what is the difference between them, do they do the same thing? why does one have a return and the other one makes changes to the calling object?
Which one is better?
In general, how should I return objects?
public Monom Der()
{
double a = this.get_coef() * this.get_pow();
int b = this.get_pow() - 1;
return new Monom(a, b);
}
public void Der()
{
this.set_coefficient(this._power * this._coefficient);
this.set_power(this._power - 1);
}

This one
public Monom Der() {
double a = this.get_coef() * this.get_pow();
int b = this.get_pow() - 1;
return new Monom(a, b);
}
does not change the state of the instance, it is useful when you want to have immutable objects. It can be used to work with both states the initial state and the state after process
Monom initialMonom = new Monom(2, 2);
Monom theNewMonom = initialMonom.Der();
// do something with both initialMonom and theNewMonom
This one
public void Der() {
this.set_coefficient(this._power * this._coefficient);
this.set_power(this._power - 1);
}
changes the state of the current instance, so the instance is NOT immutable. It can be useful when the instance needs to be reused
Monom initialMonom = new Monom(2, 2);
// do something with initial monom
initialMonom.Der(); // mutate the initial monom
// do something with the new state

You can Google a bit for the details. It's quite many things at the beginning here.
Differences: One is returned an Object Monom, one is "void"
Why: It depends on your business or the purpose of the codes that you would like to build. Returned Object is used by the next step or just show data. "void" means you don't want to get any data but to do some actions in that method
Which is better: It's hard to say. As the previous explanation, it should depend on your need
How should you return: refer this: https://docs.oracle.com/javase/tutorial/java/javaOO/returnvalue.html
Keep going to search more/practice more. Then it's easier.
Hope this help.

The first method creates a new object which will contain the result of the operations, but do not affect the current object, the second one directly changes the object you're using.

While you say that both methods do the same, this it not neccessarily true, since your first method caluclates a result and returns it, your second method calculates the result, but assigns it to a state in the current object.
Lets consider the following class:
public class Dinner {
private Meal meal;
public Dinner(Meal meal) {
this.meal = meal;
}
public Meal getMeal(Meal meal) {
return meal;
}
public setMeal(Meal meal) {
this.meal = meal;
}
}
Here, setMeal modified the internal state of the object, but it has no return value. On the other hand, getMeal return the current state of the object, but does not modify it.
Think about what exactly you need in your use case: If you want to modify internal data of an object, then go with the second way. If you want to return for example, the result of a calculation or internal state, give something back to the caller, so he can operate with it.
In the end, this are just some ideas, implementing a particular problem always comes with a lot of different possibilities so there is no perfect answer to this question.

Related

How to use method result properly in Java

I will use result of a method call in some calculation. I have two ways:
Invoke method once and store the return into a local value, then use the local value in some calculation.
Use call method many times.
Please see my sample code:
public class TestMethod {
public void doSomething_way1() {
String prop1 = this.getProp1();
if (prop1 != null) {
String value = prop1 + " - another value";
System.out.println(value);
}
}
public void doSomething_way2() {
if (this.getProp1() != null) {
String value = this.getProp1() + " - another value";
System.out.println(value);
}
}
public String getProp1() {
return "return the same value";
}
}
NOTE that, the method doSomething will be invoked a lots at a time ( In web environment )
Can someone show me which way I should use in the case the result of method will be used at least 3 times?
I believe using the method call many times is more intuitive and makes the code more readable.
In your case it wont matter even if you give call to the getProp1() method multiple times. Because it does not perform any computation, object creation or I/O operation which may cause performance issues.
You could go a step further:
public void doSomething_way2() {
if (this.getProp1() != null) {
System.out.println(this.getProp1() + " - another value");
}
}
If the method is getting called a lot (I mean many, many times a second), creating the extra variable could change performance a tiny bit with respect to garbage collection and what not... I think its trivial.
In some cases, getting the value more than once could raise thread-safety issues, if the value weren't final, whereas if you fetch the value once, at least the entire operation of way1 will be consistent with a single value for prop1.
But even if threading weren't an issue, I still think it's better, stylistically, to 'cache' the value in a local variable which is well named.
(I'm assuming that your real code does something more significant than return the fixed String "something") - the getProp1 method as written is pretty thread-safe. :)
From a performance standpoint, at least from the examples given, it does not appear to be any fundamental difference doing it one way or another. Object allocations for small numbers of iterations (unless they are heavyweight objects) should be minimal.
However, from a programming design and implementation standpoint, it may be helpful to keep the program 'cohesive', i.e. have classes more closely represent things.
In which case the local variable from the return of the method (as it is a different 'thing') and subsequent calculation.
e.g.:
interface Dog{
void wagTail();
Dung eat(DogFood f);
}
interface Human{
void pickUpDung(Dung d);
}
codeLoop(Human m, Dog d, DogFood f){
d.wagTail();
Dung poo = d.eat(f);
m.pickUpDung(poo);
}
whereas a less cohesive example would be
interface Dog{
void wagTail();
void eatAndHaveHumanPickUp(DogFood f);
}
// you can fill in the rest...
it wouldn't follow the principle of cohesion, because you wouldn't normally expect a dog call to have this kind of method...

How to make clear that a parameter of a method serves as a return value?

Is there a way to show that a parameter of a method serves as return value?
If I want to return one value it is no problem:
public Set<Integer> addIntegerToSet(final int i) {
Set<Integer> intSet = new HashSet<>();
intSet.add(i);
return intSet;
}
It's easy to see that the method returns a set.
But if I want a method to return two values I need a workaround:
public Set<Integer> addIntegerToSet(final int i, Set<Integer> returnIntMap) {
Set<Integer> intSet = new HashSet<>();
intSet.add(i);
returnIntMap.add(i);
return intSet;
}
These two pieces of code are just examples to illustrate my question and they have no practical use.
However, I want to make it obvious to the user that this set (returnIntMap) was manipulated as well. It is common practice to put a "final" in front of parameters that are not manipulated within a method, but this is not done consequently, not even in Java standard classes.
So, how do I show that returnIntMap is manipulated within the method, without just mentioning it in the java doc comments. Are there any conventions?
It is not directly possible in Java.
Java uses pass by value. Objects and Arrays are actually pointers, so even though it looks like pass by reference, actually the reference is passed as value. This means you can modify the object, but not the reference to it.
final is not used that much, because it merely states that the pointer cannot be modified, but the object it points to can. Thus there is not much use to declare arguments to methods as final in a public interface. It is a nice safeguard in the actual implementation, though. In short: final != const and Java has no equivalent of const.
Even though you can technically only return one object, nothing stops you from returning a container that wraps several new objects into one.
If you just want to (internally) document which objects are modified you can use annotations to mark parameters as e.g. #ReadOnly or #ReadWrite. These are not part of the standard or any library I know, though there might very well exist one. Even if not, you can still define your own annotations.
What you want to is do a pass by reference to your method arguments. That does not happen in Java. Java does a pass by value.
You can't really mark a parameter as IN or IN/OUT. You could write a more cleaner code, having your two return parameters in a new class. So you have both return parameters as the one and only return parameter:
public class ReturnParam {
private final Set<Integer> intSet;
private final Set<Integer> returnIntMap;
public ReturnParam(final Set<Integer> intSet, final Set<Integer> returnIntMap) {
this.intSet = intSet;
this.returnIntMap = returnIntMap;
}
public Set<Integer> getIntSet() {
return intSet;
}
public Set<Integer> getReturnIntMap() {
return returnIntMap;
}
}
// and your method could look like this
public ReturnParam addIntegerToSet(final int i) {
Set<Integer> intSet = new HashSet<>();
Set<Integer> returnIntMap = new HashSet<>();
intSet.add(i);
returnIntMap.add(i);
return new ReturnParam(intSet, returnIntMap); // put it into the ReturnParam wrapper class
}
I am speaking of a work around.
Since you are passing the set, and the method is also returning a set. So you can compare them in your calling method whether something has been changed or not.
(you can achieve comparison by firstSet.equals(secondSet) or firstSet.containsAll(secondSet))
Firstly, you could do this -
public static Set<Integer> addIntegersToSet(Set<Integer> set, final int ... arr) {
// <-- Receive a Set and a
// variable number of ints.
for (int i : arr) { // add each int to the set (possibly none to add).
set.add(i);
}
return set; // return the set.
}
Then you could check the set size before (and after) to see how many integer(s) you added to your set.
To make your set immutable you can use Collections.unmodifiableSet. See documentation. But then you can't add anything to the Set. I think you'd want to document when you changed a Set in that way.

immutable objects and lazy initialization.

http://www.javapractices.com/topic/TopicAction.do?Id=29
Above is the article which i am looking at. Immutable objects greatly simplify your program, since they:
allow hashCode to use lazy initialization, and to cache its return value
Can anyone explain me what the author is trying to say on the above
line.
Is my class immutable if its marked final and its instance variable
still not final and vice-versa my instance variables being final and class being normal.
As explained by others, because the state of the object won't change the hashcode can be calculated only once.
The easy solution is to precalculate it in the constructor and place the result in a final variable (which guarantees thread safety).
If you want to have a lazy calculation (hashcode only calculated if needed) it is a little more tricky if you want to keep the thread safety characteristics of your immutable objects.
The simplest way is to declare a private volatile int hash; and run the calculation if it is 0. You will get laziness except for objects whose hashcode really is 0 (1 in 4 billion if your hash method is well distributed).
Alternatively you could couple it with a volatile boolean but need to be careful about the order in which you update the two variables.
Finally for extra performance, you can use the methodology used by the String class which uses an extra local variable for the calculation, allowing to get rid of the volatile keyword while guaranteeing correctness. This last method is error prone if you don't fully understand why it is done the way it is done...
If your object is immutable it can't change it's state and therefore it's hashcode can't change. That allows you to calculate the value once you need it and to cache the value since it will always stay the same. It's in fact a very bad idea to implement your own hasCode function based on mutable state since e.g. HashMap assumes that the hash can't change and it will break if it does change.
The benefit of lazy initialization is that hashcode calculation is delayed until it is required. Many object don't need it at all so you save some calculations. Especially expensive hash calculations like on long Strings benefit from that.
class FinalObject {
private final int a, b;
public FinalObject(int value1, int value2) {
a = value1;
b = value2;
}
// not calculated at the beginning - lazy once required
private int hashCode;
#Override
public int hashCode() {
int h = hashCode; // read
if (h == 0) {
h = a + b; // calculation
hashCode = h; // write
}
return h; // return local variable instead of second read
}
}
Edit: as pointed out by #assylias, using unsynchronized / non volatile code is only guaranteed to work if there is only 1 read of hashCode because every consecutive read of that field could return 0 even though the first read could already see a different value. Above version fixes the problem.
Edit2: replaced with more obvious version, slightly less code but roughly equivalent in bytecode
public int hashCode() {
int h = hashCode; // only read
return h != 0 ? h : (hashCode = a + b);
// ^- just a (racy) write to hashCode, no read
}
What that line means is, since the object is immutable, then the hashCode has to only be computed once. Further, it doesn't have to be computed when the object is constructed - it only has to be computed when the function is first called. If the object's hashCode is never used then it is never computed. So the hashCode function can look something like this:
#Override public int hashCode(){
synchronized (this) {
if (!this.computedHashCode) {
this.hashCode = expensiveComputation();
this.computedHashCode = true;
}
}
return this.hashCode;
}
And to add to other answers.
Immutable object cannot be changed. The final keyword works for basic data types such as int. But for custom objects it doesn't mean that - it has to be done internally in your implementation:
The following code would result in a compilation error, because you are trying to change a final reference/pointer to an object.
final MyClass m = new MyClass();
m = new MyClass();
However this code would work.
final MyClass m = new MyClass();
m.changeX();

Change the state of an object that is stored in a set

Is there any good advice how to deal with mutable objects that are stored in Sets?
Some objects may define their equality (and hashCode) based on their internal state. When such objects are stored in Sets, in- or outside the controlled code, a mutation of the state may lead to inconsistency in the Set.
Is there any "best-practice" to avoid or deal with that, aside don't do it?
Example code:
static class A {
String s;
public boolean equals(Object o) {
return s.equals(((A)o).s);
}
public int hashCode() {
return s.hashCode();
}
public String toString() {
return s;
}
}
public static void main(String[] args) {
A a0 = new A();
a0.s = "Hello";
A a1 = new A();
a1.s = "World";
HashSet<A> set = new HashSet<A>();
set.add(a0);
set.add(a1);
System.out.println(set);
a0.s = "World";
System.out.println(set);
}
At some point the development team got this problem a lot when working with collections of entities that only got their key before being stored to the database. Their hashcode/equals depended on that key...
The solution we came up with was something along these lines:
public static <P> void rearrange(Set<P> set) {
HashSet<P> temp = new HashSet<P>();
temp.addAll(set);
set.clear();
set.addAll(temp);
}
Another idea was a Set implementation decorating a HashSet, but we quickly decided this would cause more problems on the long run. For the most part the above method is executed by 'framework' code transparently to the developer, but I am still not particularly happy with this solution.
Set interface doesn't provide any method for getting a value and there is a reason to do that.
Java Set API
So it doesn't expect that you get a value, modify it and then add it again. In your code that's what you doing; you modified a value stored in Set.
So ideally you should avoid it but if you want to modify any object inside Set then do below steps:
Remove Object from Set
Add a new modified object
This way your hashcode/equality contract will be guaranteed.

Output Parameters in Java

With a third party API I observed the following.
Instead of using,
public static string getString(){
return "Hello World";
}
it uses something like
public static void getString(String output){
}
and I am getting the "output" string assigned.
I am curious about the reason of implementing such functionality. What are the advantages of using such output parameters?
Something isn't right in your example.
class Foo {
public static void main(String[] args) {
String x = "foo";
getString(x);
System.out.println(x);
}
public static void getString(String output){
output = "Hello World"
}
}
In the above program, the string "foo" will be output, not "Hello World".
Some types are mutable, in which case you can modify an object passed into a function. For immutable types (such as String), you would have to build some sort of wrapper class that you can pass around instead:
class Holder<T> {
public Holder(T value) {
this.value = value;
}
public T value;
}
Then you can instead pass around the holder:
public static void main(String[] args) {
String x = "foo";
Holder<String> h = new Holder(x);
getString(h);
System.out.println(h.value);
}
public static void getString(Holder<String> output){
output.value = "Hello World"
}
That example is wrong, Java does not have output parameters.
One thing you could do to emulate this behaviour is:
public void doSomething(String[] output) {
output[0] = "Hello World!";
}
But IMHO this sucks on multiple levels. :)
If you want a method to return something, make it return it. If you need to return multiple objects, create a container class to put these objects into and return that.
I disagree with Jasper: "In my opinion, this is a really ugly and bad way to return more than one result".
In .NET there is a interesting construct that utilize the output parameters:
bool IDictionary.TryGet(key, out value);
I find it very usefull and elegant. And it is the most convenient way to aks if an item is in collection and return it at the same time. With it you may write:
object obj;
if (myList.TryGet(theKey, out obj))
{
... work with the obj;
}
I constantly scold my developers if I see old-style code like:
if (myList.Contains(theKey))
{
obj = myList.Get(theKey);
}
You see, it cuts the performance in half. In Java there is no way to differentiate null value of an existing item from non-existance of an item in a Map in one call. Sometimes this is necessary.
This functionality has one big disadvantage - it doesn't work. Function parameters are local to function and assigning to them doesn't have any impact outside the function.
On the other hand
void getString(StringBuilder builder) {
builder.delete(0, builder.length());
builder.append("hello world");
}
will work, but I see no advantages of doing this (except when you need to return more than one value).
Sometimes this mechanism can avoid creation of a new object.
Example:
If an appropriate object exists anyhow, it is faster to pass it to the method and get some field changed.
This is more efficient than creating a new object inside the called method, and returning and assigning its reference (producing garbage that needs to be collected sometime).
String are immutable, you cannot use Java's pseudo output parameters with immutable objects.
Also, the scope of output is limited to the getString method. If you change the output variable, the caller won't see a thing.
What you can do, however, is change the state of the parameter. Consider the following example:
void handle(Request r) {
doStuff(r.getContent());
r.changeState("foobar");
r.setHandled();
}
If you have a manager calling multiple handles with a single Request, you can change the state of the Request to allow further processing (by other handlers) on a modified content. The manager could also decide to stop processing.
Advantages:
You don't need to return a special object containing the new content and whether the processing should stop. That object would only be used once and creating the object waste memory and processing power.
You don't have to create another Request object and let the garbage collector get rid of the now obsolete old reference.
In some cases, you can't create a new object. For example, because that object was created using a factory, and you don't have access to it, or because the object had listeners and you don't know how to tell the objects that were listening to the old Request that they should instead listen to the new Request.
Actually, it is impossible to have out parameters in java but you can make a work around making the method take on a de-reference for the immutable String and primitives by either writing a generic class where the immutable is the generic with the value and setter and getter or by using an array where element 0 (1 in length) is the value provided it is instantiate first because there are situations where you need to return more than one value where having to write a class just to return them where the class is only used there is just a waste of text and not really re-usable.
Now being a C/C++ and also .Net (mono or MS), it urges me that java does not support at least a de-reference for primitives; so, I resort to the array instead.
Here is an example. Let's say you need to create a function (method) to check whether the index is valid in the array but you also want to return the remainding length after the index is validated. Let's call it in c as 'bool validate_index(int index, int arr_len, int&rem)'. A way to do this in java would be 'Boolean validate_index(int index, int arr_len, int[] rem1)'. rem1 just means the array hold 1 element.
public static Boolean validate_index(int index, int arr_len, int[] rem1)
{
if (index < 0 || arr_len <= 0) return false;
Boolean retVal = (index >= 0 && index < arr_len);
if (retVal && rem1 != null) rem1[0] = (arr_len - (index + 1));
return retVal;
}
Now if we use this we can get both the Boolean return and the remainder.
public static void main(String[] args)
{
int[] ints = int[]{1, 2, 3, 4, 5, 6};
int[] aRem = int[]{-1};
//because we can only scapegoat the de-ref we need to instantiate it first.
Boolean result = validate_index(3, ints.length, aRem);
System.out.println("Validation = " + result.toString());
System.out.println("Remainding elements equals " + aRem[0].toString());
}
puts: Validation = True
puts: Remainding elements equals 2
Array elements always either point to the object on the stack or the address of the object on the heap. So using it as a de-references is absolutely possible even for arrays by making it a double array instantiating it as myArrayPointer = new Class[1][] then passing it in because sometimes you don't know what the length of the array will until the call going through an algorithm like 'Boolean tryToGetArray(SomeObject o, T[][] ppArray)' which would be the same as in c/c++ as 'template bool tryToGetArray (SomeObject* p, T** ppArray)' or C# 'bool tryToGetArray(SomeObject o, ref T[] array)'.
It works and it works well as long as the [][] or [] is instantiate in memory first with at least one element.
in my opinion, this is useful when you have more than one result in a function.

Categories

Resources