How to use method result properly in Java - 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...

Related

Java - Creating string with constant value inside function

Which one is better?
public class A {
private static final String DOSOMETHING_METRICS = "doSomethingmetrics";
private static final String SAYSOMETHING_METRICS = "saySomethingmetrics";
public void doSomething() {
...
System.out.println("Metrics for " + DOSOMETHING_METRICS + "is something");
}
public void saySomething() {
...
System.out.println("Metrics for " + SAYSOMETHING_METRICS + "is something");
}
}
OR
public class A {
public void doSomething() {
final String DOSOMETHING_METRICS = "doSomethingmetrics";
...
System.out.println("Metrics for " + DOSOMETHING_METRICS + "is something");
}
public void saySomething() {
final String SAYSOMETHING_METRICS = "saySomethingmetrics";
...
System.out.println("Metrics for " + SAYSOMETHING_METRICS + "is something");
}
}
I think Method 1 wins in case of memory optimization as compiler allocated memory only once and the garbage collector doesn't need to deallocate the string created in every function call. However, I think good coding practice recommends that variable should be bound to the scope in which it has to be used and constants should be defined as close as to they first use in the program which is where Method 2 wins.
What is your take on this? Which aspect is more important? The functions here will be called multiple times (let's say at least 100K times).
In both cases, these are constant variables as defined in JLS 4.12.4. So not only are the strings "doSomethingmetrics" and "saySomethingmetrics" interned, but so are "Metrics for doSomethingmetricsis something" and "Metrics for saySomethingmetricsis something". (Yeah, you need to add a space before "is".)
The first version logically has a slightly smaller stack, but I'd expect the JIT to optimize that away anyway.
I would use whichever form you find most readable. If you want to know for sure about the performance in your particular app, then as ever, the right thing to do is test both ways.
Looking at the results of javap -v, it looks like the second method actually has a slight advantage in that the unconcatenated strings don't even need to appear in the constant pool, as there's no way of reaching them. So you should see your class file being ever-so-slightly smaller that way. But again, I very much doubt that it'll make any difference.
I think Method 1 wins in case of memory optimization
In both cases your string constants go to string pool and stored there. In second case you reallocate space for reference to your variable in stack frame. That's why I think that the first one is preferred one (but compiler can optimize the second case and they would be the same).

Java: What is the best approach to validate the method arguments for null

What is the best approach to validate the arguments for null while calling a method?
1) before making the method call
private void myMethod(String param1, String param2){
String a = param2;
if(StringUtils.isNotBlank(a)){
validate(a);
}
}
private void validate(String a) {
int temp = Integer.parseInt(a);
if(a > 4){
addError()
}
}
2) inside the method once you receive the arguments
private void myMethod(String param1, String param2){
String a = param2;
validate(a);
}
private void validate(String a) {
if(StringUtils.isNotBlank(a)){
int temp = Integer.parseInt(a);
if(a > 4){
addError()
}
}
}
OR Both
IMO, StringUtils.isNotBlank(a) is some form of validation only, so it should be in validate() method. And if that has to be checked every time you call validate() method, then certainly it will make more sense to move it there.
From the two approaches you give, the second is better.
Reason: DRY principle (Don't Repeat Yourself aka avoid code duplication).
The code in the first snipped duplicates (or triplicates, etc) the "check for blank" part of the code for every place validate() is called.
Also the responsibility of the consistency, the "not blank" invariant (a domain/business rule), belongs (is inherent) to the validate() method, so it should have the responsibility for taking care of it.
In practical terms: Consider the possibility of a change to this domain rule, if one needed to add some new check to it, in what case you'd have to change less (thus less error-prone)? Where the developer that'll do the change would expect to find such rule? In the validate() or scattered through the whole code base?
If that error validation is useful everytime you call some method, it obviously should be done inside the method, or else you would have to do it everytime before calling that method. Just remember to comment the code, so you remember that later.
Conceptually the validate() method should capable to identify that the passing parameter is null or not. So in your given scenario the approach 2 should be preferable.
Would be inside the method throwing a java.lang.IllegalArgumentException.
Like:
private void validate(String a) {
if(StringUtils.isNotBlank(a)){
int temp = Integer.parseInt(a);
if(a > 4){
addError()
}
}
else{
throw new IllegalArgumentException("argument must not be null or blank");
}
}
What is the best approach to validate the arguments
IMO, your second approach is better one
because it is not a task for which you have to provide a separate method, it is just a parameter validation which is part of same logic which you are going to implement in your method. and another thing to be considered is second approach will form higher redability of your code.
OR Both
NEVER, Choose one as per your coding practice and stick to it.
Other considerations for validation :
Check parameters annotated with #Nonnull for null?
You can use assertion for Private arguments.

Is it a bad practice to use arrays as parameter(s) to return multiple values

I sometimes (actually, often) find myself using a one-element array to return multiple values from a method. Something like this:
public static int foo(int param1, int param2[], String param3[])
{
// method body
....
// set return values
param2[0] = <some value>;
param3[0] = <some value>;
return <some value>;
}
Is this a bad practice? (It seems like it is because some of my friends said they didn't know what it was doing for 2 seconds!)
But the reason I used this in the first place was because this looked closest to what is know as pass-by-reference in C++. And the practice wasn't discouraged in C++, so ...
But if this is really a wrong way of doing things, any idea how to rewrite this in the clean way?
Thanks
Create an object that contains the data you want to return.
Then you can return an instance of that object.
class FooData {
private int someInt;
private int anotherInt;
private String someString;
public FooData(int a, int b, String c) {
someInt = a;
anotherInt = b;
someString = c;
}
}
public FooData foo() {
// do stuff
FooData fd = new FooData(blah, blahh, blahhh);
return fd;
}
While I agree with the general opinion here that using arrays for such a purpose is bad practice, I'd like to add a few things.
Are you sure that "pass by reference" really is what you need in the first place?
Many have said that your code is bad style, but now let me tell you why that is IMHO.
"Pass by reference" is mostly a synonym for "programming by side effect" which is a thing you always want to avoid. It makes code much harder to debug and understand, and in a multi-threaded environment, the bad effects of this attitude really can hit you hard.
To write scalable and thread-safe code in Java, you should make objects "read-only" as much as possible, i.e. ideally, you create an object and initialize it at the same time, then use it with this unmodifiable state throughout your application. Logical changes to the state can almost always be considered a "creation" of new state, i.e. creation of a new instance initialized to a state then needed. Many modern scripting languages only let you work in this way, and it makes things much easier to understand.
As opposed to C++, Java is much more efficient in allocating and releasing short-lived objects, so there is actually nothing wrong with what others here have suggested: To create an instance of a special class to hold the function result, just for the purpose of returning the result. Even if you do that in a loop, the JVM will be smart enough to deal with that efficiently. Java will only allocate memory from the OS in very large chunks when needed, and will deal with object creation and release internally without the overhead involved in languages like C/C++. "Pass by reference" really doesn't help you very much in Java.
EDIT: I suggest you search this forum or the net for the terms "side-effect", "functional programming" or "immutability". This will most likely open a new perspective to your question.
I believe that it is bad practice to "return" values using one-element arrays that are parameters to your method.
Here's another SO question about this topic. In short, it's very bad for readability.
There is an easy workaround: Wrap all values that you wish to return in a class you define specifically for this purpose, and return an instance of that class.
return new ValueHolder(someValue1, someValue2, someValue3);
That's not very idiomatic java. There are usually better approaches to software design.
What you're really doing with the "one-element array" is creating a mutable object (since String is immutable, as are primitives like int) and passing it by reference. Modifying this mutable object is called a "side effect" of the method. In general, you should minimize mutability (Effective Java Item 15) and your methods should be side-effect free. There are a couple approaches here.
1. Split the method into two (or three) methods that all take the same params:
public static int foo1(int param1)
{
// method body
....
return <some value>;
}
Similarly, you might have
public static int foo2(int param1) { ... }
and
public static String foo3(int param1) { ... }.
2. Return a composite object.
public Container {
private final int originalReturn;
private final int param2;
private final String param3;
public Container(int originalReturn, int param2, String param3) {
this.originalReturn = originalReturn;
this.param2 = param2;
this.param3 = param3;
}
// getters
}
public static Container foo(int param1, int param2[], String param3[])
{
// method body
....
// set return values
return new Container(<some value>, <some value>, <some value>);
}
This is indeed bad practice if the values are unrelated. This is usually an indicator that you can split that function into two, with each returning one of the values.
EDIT:
I am assuming that you are returning two values calculated in the method in an array. Is this not the case?
e.g.
public int[] getStatistics(int[] nums)
{
//code
int[] returns = new int[2];
returns[0] = mean;
returns[1] = mode;
return returns;
}
The above function could be split into getMean() and getMode().
Passing variables by reference allows the function to "legally" change their value. See this article to clear up the confusion of when this is possible in Java, and when it's not...
This is bad practice if the values are of different type and different entities, e.g. name and address, etc. It is fine with create an array with same data type, e.g list of addresses.

Pass by Reference and recursion

I have the following recursive function prototype:
public void calcSim(Type<String> fort, Integer metric)
Integer metric = 0;
calcSim(fort, metric);
System.out.println("metric: " + metric);
}
I want to print the value of metric as shown above. However it is always zero. Now, when I print at the end of the function, I do get a valid number.
How do I pass by reference or get the equivalent functionality like in C++
What all can I do with regards to my parameter passing? (by value, by reference, etc...)
There is no such thing as pass by reference in Java, sorry :(
Your options are either to give the method a return value, or use a mutable wrapper and set the value as you go. Using AtmoicInteger cause it is in JDK, making your own that doesn't worry about threadsafety would of course be mildly faster.
AtomicInteger metric = new AtomicInteger(0);
calcSim(fort, metric);
System.out.println("metric: " + metric.get());
Then inside the calcSim set it with metric.set(int i);
To get the behavior of pass by reference, you can create a wrapper class, and set the value in that class, eg:
class MyWrapper {
int value;
}
Then you can pass a MyWrapper to your method and change the value, for example like this:
public void calcSim(Type<String> fort, MyWrapper metric)
metric.value++;
System.out.println("metric: " + metric.value);
calcSim(fort, metric);
}
Integer is wrapper class. Wrapper classes are immutable. So, what you are expecting can't be achieved with Integer type.
You may create mutable wrapper class around primitive and update the object to achieve what you want.
Two big issues:
You are redefining metric with the same name in your method as well. How is program printing anything. It should complain at compilation time.
No defined exit criteria. Does you program(method) stops?
I think you wanted something as (pseudo code as I don't know what are you doing):
public void calcSim(Type<String> fort, Integer metric)
if(condtion){
//print or return
}else{
//modify fort or metric so that it exits
calcSim(fort, metric); //call this with modified value
System.out.println("metric: " + metric.value);
}
}

Java Best Practices: Performance with method parameters

Which is faster and/or less resources consuming:
class Foo()
{
public int value;
}
This way?
public int doSomeStuff(Foo f)
{
return (f.value + 1);
}
public int doOtherStuff()
{
...
Foo f = new Foo();
int x = doSomeStuff(f);
...
)
or this way?
public int doSomeStuff(int v)
{
return (v + 1);
}
public int doOtherStuff()
{
...
Foo f = new Foo();
int x = doSomeStuff(f.value);
...
)
In both cases, "doSomeStuff" will not change nothing in foo class. It just needs to know the "value".
They both perform the same, the same sequence of operations occurs. Your main concern is maintainability and sensible design here. Think carefully about which methods need which data and design it properly.
If you do have issues, you can optimise later. But you should always optimise last.
In terms of resource consuming, it is exactly the same.
But the second option is clearly better in terms of programming because if doSomeStuff only needs value, then there is no point to passing f.
I don't think there is any performance difference at all. And Java compiler will optimize to the best one anyway...
Depends how often you're going to call doSomeStuff without calling doOtherStuff, but generally performance difference is negligible and if you only call doOtherStuff then they'll be equally performant.
Probably even better:
Decalre doSomeStuff() as a method of foo, and invoke: f.doSomeStuff()
It is much more readable and will be easier to maintain doing it so, since if you have a
sub class of foo: Bar, and you want to calculate things a bit different - all you have to do is override doSomeStuff() in Bar
You should prefer readability over micro optimizations - let the compiler take care of those for you.
code snap:
class foo() {
public int value;
public int doSomeStuff() {
return value + 1;
}
}
and:
public int doOtherStuff() {
...
foo f = new foo();
int x = f.doSomeStuff();
...
}
The difference between doing:
object.intvariable + 1
and
int + 1
is so negligible as to be irrelevant for real world apps. It's probably one or two more JVM opcodes to look up foo and find its value variable which is not worth mentioning. You'd never notice that unless you were trying to create a pseudo real-time app in Java (which is all but an exercise in futility).
However, that said, the way you are doing it is very bad. You should not be exposing value directly, but be using proper data encapsulation via getter and setter methods.
It does not matter from performance perspective.
The recommendation is: do not think about pre-mature optimization. Think about correctness and good design of your code.
For example your code
Does not follow naming conventions: class names must start with capital letter
Contains public fields. It is forbidden. Use bean notation (getters and setters).
Cannot be compiled (there is no type integer. Choose among int and Integer

Categories

Resources