Good practice in using properties and local variables - java

Is it a good practice to use properties as local variable. In cases where there are many methods which uses some variables, In each method the variable value changes. This avoids many times creating new variables and the code increases. Any suggestion?
private void method1(){
int totalLength = length1 + 10;
int totalBreath = (breath1 + breath2) + 20;
int size = (totalLength * totalLength);
System.out.println(size);
}
private void method2(){
int totalLength = length1 + 20;
int totalBreath = (breath1 + breath2) + 30;
int size = (totalLength * totalLength);
System.out.println(size);
}
private void method3(){
int totalLength = length1 + 60;
int totalBreath = (breath1 + breath2) + 10;
int size = (totalLength * totalLength);
System.out.println(size);
}
As you can see, totalLength, totalBreath, size is repeated in every method. Can i make them as fields of the class? So, i need not declare it in every method.
private void method1(){
totalLength = length1 + 10;
totalBreath = (breath1 + breath2) + 20;
size = (totalLength * totalLength);
System.out.println(size);
}

I read your question as, "When should a local variable be promoted to be a field of the class?"
The best answer is "it depends" but then again, its accuracy is quickly eclipsed by its lack of usefullness.
Fields should have a relationship to the class itself, as in is the field an attribute of the class? I include an example below to illustrate the syntax difference, but I agree with this post that it should be avoided if it pollutes the meaning of the class.
Usually you only need to have a field when you need the value of the field to be maintained between calls to different methods for a given instance of the class, with the option of making it static when the value should be maintained between method calls for all instances of the class. It will depend on several factors like shop convensions, performance goals, existing codebase, etc. so there is no single right answer without specific code. This question seems to include similar points. If you find yourself using the approach below, you might consider other approaches like refactor the behavior into a help class.
Another question asks the same question but from the perspective of a programming student.
Examples:
public class VariableScope {
int field1 = 3;
void foo() {
int a = 2;
// variable passing in width
bar1(1);
bar2(1);
// variable passing in depth
bar3(a);
// uses a field to reduce variable passing
baz1();
baz2();
}
void bar1(int param) {
System.out.println("param=" + param);
}
void bar2(int param) {
System.out.println("param=" + param);
}
void bar3(int param)
{
System.out.println("Passing param to bar4");
bar4(param);
}
void bar4(int param){
System.out.println("param=" + param);
}
void baz1() {
System.out.print("field1=" + field1);
}
void baz2() {
System.out.print("field1=" + field1);
}
}

From what it sounds like, if you're using the variable for multiple methods you're should declare the variable as a global variable. But yes, If no other method needs that variable , and you don't want to be writing a bunch of return statements you can use local variables

I suppose you mean a field by property which usually has accessor and mutator (get,set-methods).
In common you should keep the scope of a variable as small as possible. An example if you use many for loops like:
for ( int i = 0 ; i < 10 ; i++ ) {
}
and replace this by
int i;
method1() {
for ( i = 0 ; i < 10 ; i++ ) {
// some code;
}
}
method2() {
for ( i = 0 ; i < 10 ; i++ ) {
// some code;
}
}
If one thread calls method1() and another one method2() you would face a race condititon.
You can easily introduce hard to find bugs in your code.

I assume you mean something like this:
Class foo() {
int x;
public bar() {
for(x = 0; x <100; ++x) ...
} }
No, it's not good practice.
One place where it can even be harmful is in the synchronization/concurrency/multi-threaded case: if you are working with class members, they are going to need be synchronized which will eat into performance. Otherwise you risk multiple threads overwriting the value of the field and that can lead to errors in your program (likely hard to debug).

Related

Is there a way to force a variable out of existence in Java?

Basically, my goal is to be as efficient as possible by "deleting" variables when I'm done with them, even if still in scope. So far, I've been using if(true) to manually create a scope that defines the lifetime of variables, but I'm looking for something like, var.close(), a function that's only purpose is to cause a variable to essentially go out of scope and no longer have a memory location reserved for it.
The example I use below could obviously use for() to sidestep this particular instance(the assignment wants me not to use for()), but my concern is wider than variables used as indexes.
(ignore any other logic/syntax errors present, as I haven't proofread this yet)
package root;
import javax.swing.JOptionPane;
public class DebugEight4
{
public static void main(String[] args)
{
String array[] = new String[100];
String entry = " ";
final String STOP = "/']";
StringBuffer message = new StringBuffer(
"The words in reverse order are:\n"
);
if(true)
/*
*forces x out of scope
* after while statement ends
*/
{
int x = 0;
while(!entry.equals(STOP))
{
entry = JOptionPane.showInputDialog(null,
"Enter another word\n" +
"Enter " + STOP + " when you want to stop");
if(!entry.equals(STOP) && x != 100)//prevents fragmentation error
{
array[x] = entry;
}
else
{
JOptionPane.showMessageDialog(null, "That\'s all! Let's see the results.");
}
++x;
}
}/* end x scoping if
* If the if(true) wasn't here, x would still exist!
*/
for(int y = array.length-1; y > 0; --y)
{
message.append(array[y]);
message.append("\n");
}
JOptionPane.showMessageDialog(null, message);
}
}
Any thoughts?
This is exactly what scopes are for. You don't need to invent your own scoping system. Any variable should be declared in the smallest possible enclosing scope. But that's as far as you need to go with this. It is a visibility principle, not an efficiency principle, as all the stack needed for a method is allocated on entry to the method, and inner scopes don't correspond to bytecode instructions in any way.
To create a more-limited scope is easy enough. Just create a new block:
public static void whatever() {
int a = 5; // Exists until end of method
{
int b = 5; // Exists until end of outer block
{
int c = 5; // Exists until end of inner block
}
// c is no longer accessible
}
// b is no longer accessible
}
I'd recommend against this for a few reasons:
It's harder to read for little gain
The compiler or JIT can automatically figure out the lifetime of variables and automatically handle what you're attempting to do
You can't overlap variable lifetimes this way (nesting means that the most-nested variable must expire off the stack before less-nested ones)

How do I use the values of variables that are calculated inside a method, in a class?

I'm very new to programming, and don't understand much. I've been trying to build a simple game where a user and computer compete by rolling dice to earn points. My method is posted below. The computer is only allowed to earn 20 points per turn.
My issue is that I need the value of variable computerTotal to be remembered after the method has been called and completed. I want to ensure that whenever the computerTurn method is finished, I can use that calculated variable computerTotal outside of that method.
I tried establishing a new int in the .java file class (but outside of the method), and then using that int within the method to hold the value, however I receive errors about the integer needing to be static?
This is all very confusing to me. Can anyone help me out?
public static void computerTurn()
{
System.out.println("Passed to Computer.");
Die computerDie1, computerDie2;
int computerRound, computerTotal;
computerRound = 0;
computerTotal = 0;
while (computerTotal < 21){
computerDie1 = new Die();
computerDie2 = new Die();
computerDie1.roll();
computerDie2.roll();
System.out.println("\n" + "CPU Die One: " + computerDie1 + ", CPU Die Two: " + computerDie2 + "\n");
computerRound = computerDie1.getFaceValue() + computerDie2.getFaceValue();
int cpuDie1Value;
int cpuDie2Value;
cpuDie1Value = computerDie1.getFaceValue();
cpuDie2Value = computerDie2.getFaceValue();
System.out.println ("Points rolled this round for the Computer: " + computerRound);
computerTotal = computerTotal + computerRound;
System.out.println ("Total points for the Computer: " + computerTotal + "\n");
}
Any variables created inside a method are "local variables" meaning they cannot be used outside the method. Put a static variable outside of a method to create "global variables" which can be used anywhere.
Add a method to your class
public static int getComputerTotal() { return ComputerTotal;}
Then you can get the value outside of the class by doing something like:
ComputerTurn();
ComputerTurn.getComputerTotal();
Putting the variable outside of the method is on the right track, but since this method is static (meaning it cannot access variables that depend on object instances), it can only access static variables. Declare computerTotal in the class, outside of methods, using the following:
private static int computerTotal;
You should probably do some research on object-oriented programming and what static means in Java.
Declare computerTotal as a member variable of your class, so that its value is available even outside the function.
class MyClass{
private int computerTotal ;
public void function myFunction()
{
........
......... // your calculations
computerTotal = computerTotal + computerRound;
}
public int getComputerTotal(){return computerTotal ;}
}
You have to declare the computertotal outside any methods to keep them. so like this:
public class name {
int computertotal = 0; //v=can just uuse int computertotal;
public void method() {
while(computertotal < 20) {
computertotal += 1;
}
}
}
And now he variable gets saved!
You may need to add some setters and getters to get that int from another class.
class NewClass {
private int yourInt = 1;
}
It is telling you to make it a static variable because you may be calling it in a statement like
NewClass.yourInt;
, a static variable is one that’s associated with a class, not objects of that class.
Setters and getters are methods which allows you to retrieve or set the value which is private from another class. You might want to add them in the NewClass, where your int is declared. Setters and getters looks like this.
Setter:
public void setYourInt(int newInt) {
this.yourInt = newInt;
}
Getter:
public int getYourInt() {
return this.yourInt;
}

How to combine two methods with identical calculates but different fields

How do I combine two methods that have identical calculations but operate (read and write) different fields of the class.
A VERY simplified aircode example:
class TileCalculator
{
int length;
int width;
int tileLength;
int tileWidth
int cols;
int rows;
void calculateColumns()
{
this.cols = this.width/this.tileWidth;
}
void calculateRows()
{
this.rows = this.length/this.tileLength;
}
}
As these two methods do exactly the same calculation(s) but just using different fields for their input and output it would seem sensible to combine them but I don't know how.
UPDATE: I think I may have oversimplified it to the point where answerers are trying to solve the specific case. A more realistic example is:
void calculateCols()
{
int tileCols = width/tileWidth;
int remainder = width%tileWidth;
if (remainder==0) {
// there is an exact number of whole tiles
fullTileCols = tileCols;
firstT = tileWidth;
usedTileCols = tileCols;
} else {
// there is a remainder
fullTileCols = tileCols - 1;
firstT = (remainder+tileWidth)/2;
usedTileCols = tileCols + 1;
}
}
void calculateRows()
{
int tileRows = length/tileLength;
int remainder = length%tileLength;
if (remainder==0) {
// there is an exact number of whole tiles
fullTileRows = tileRows;
firstCut = tileLength;
usedTileRows = tileRows;
} else {
// there is a remainder
fullTileRows = tileRows - 1;
firstCut = (remainder+tileLength)/2;
usedTileRows = tileRows + 1;
}
}
I'm not saying a redesign isn't the answer but as you can see there are multiple fields involved so a simple return value probably isn't going to cut it. This is why I am using fields rather than a simple function and the maintainability of the current setup is of concern to me.
No, I wouldn't combine them, I would change them.
I'd get rid of rows and cols fields
I'd get rid of the above methods as it makes your object's state dependent on these methods always being called before an object is used -- a risky proposition.
Instead I'd create two calculated getter methods. This way the calculations are guaranteed to be done when needed.
e.g.,
public int getColumns() {
return width / tileWidth;
}
public int getRows() {
return length / tileLength;
}
Edit
I suppose you could create a RowCol class that has full, first, and used fields, and that has but one equation for doing the calculation above, and that you create two instances, one for row and one for column in the containing class, but if the rationale for this is to just combine these small methods, I question the need for this, or the benefit. Yes, you should follow the DNRY rule, but I worry more about this when I have three or more repeats of the same code.
You could make a convenience method. In the case you have shown this is actually more typing, longer program, extra complexity etc for no benefit. But if the calculation was more complicated it could be worth it
int calculate(int a, int b)
{
return a/b;
}
void calculateColumns()
{
this.cols = this.calculate(this.width, this.tileWidth);
}
after the update
you actually want 3 return values(full, first, used) so alter the "calculate" to either return a special class with 3 int or an array of int
Then feed in a and b as before but with the adjusted logic and return the 3 values and set them in the calling function
There is no easy way to do this in Java prior to Java 8. You can do it, but it involves using private internal interfaces and anonymous classes. It isn't worth it unless you're really talking about a lot of common lines of code.
With Java 8 though, you'll be able to use closures which will greatly simplify this kind of cases.

improve calling next method in JAVA

I'm looking for a better way to organize my class.
Right now my code looks like this:
mainMethod:
-number1 input
-call method1 with number1 als value
method1:
-do "stuff" with input
-call method2 with new "stuff" as value
method2:
-do stuff
-call method3
etc...
So i start with user input in my main method and my whole class works like domino, the first method needs to be called to run the next method.
I would rather have method1 return a value and save it in some global variable in my class which can be used by method2 and so on.
Here is my Code with exactly this problem: (it calculates sqrt)
package wurzel;
import java.util.Scanner;
import wurzel.Fraction;
public class wurzel {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("Eingabe:");
int in = s.nextInt();
s.close();
bisection(in);
}
private static int bisection(int N){
int counter = 0;
for(int i = 0; i < N;i++){
if((counter*counter) > N){
counter--;
break;
}
else if(counter*counter == N){
break;
}
else counter++;
}
calculateSequence(counter,N);
return counter;
}
static int[] calculateSequence(int vKomma, int look){
int m = 0;
int d = 1;
int a = vKomma;
int[] intarr = new int[4];
intarr[0] = vKomma;
for(int i = 1; i <= intarr.length; i++){
if(i == intarr.length )
break;
else{
m = (d*a) - m;
d = (look - (m*m)) / d;
a = (vKomma + m) / d;
intarr[i] = a;
}
}
calculateApproximation(intarr);
return intarr;
}
static double calculateApproximation(int[] sequence ){
Fraction result = new Fraction((sequence.length)-1);
for(int dcounter = sequence.length; dcounter > 0; dcounter--){
result = result.reciprocal().add(sequence[dcounter-1]);
}
System.out.println("Approximation als double: " +result.doubleValue());
System.out.println("Approximation als Bruch: " +result);
return result.doubleValue();
}
}
You should also seperate code into different classes. E.g. have a generic MathHelper class which has these methods in it.
This helps keep code seperate and easy to read.
You mentioned that you wanted to store some data in a global variable for the class as a whole. The way to do this is by making the class use instance methods rather than class methods. With class methods, you have to use class variables. But, when you use instance methods, you can define instance variables which can be accessed by any method within the class.
To do this, change all your methods (apart from main()) by removing the keyword static from each method. Then, define the instance variable that is global for the class. e.g. if your global variable is of type int then it would be:
private int myInstanceVariable;
This instance variable, or global variable, can be accessed by a getter and setter.
It is quite normal methods to call each other and to form long chains of calls.
So I would not worry about that. Actually in real world, in enterprise code,
you have call stack going through tens of calls. So I think global variables would
be worse practice compared to what you did.

java retain information in recursive function

Is it possible to retain information via a helper function with java, without using static variables.
For example,
public void foo(){
int v = 0;
fooHelper(2);
}
public void fooHelper(int depth){
v++;
fooHelper(depth-1)
}
Namely I want to update variable v without loosing the information for each recursive case, without having to access a variable outside the function.
Forget about all the answers that tell you to declare attributes, or to update mutable objects in each recursive call. In a true functional, recursive style you "retain" information by passing it as parameters and/or return types.
Let me illustrate with a simple example, let's say that you want to recursively calculate the sum of the elements in an int[]. Here, the state (the information that needs to be retained between recursive calls) is the current index in the array and the sum so far. Here's how to do it:
public int sum(int[] array) {
return sum(array, 0, 0);
}
private int sum(int[] array, int idx, int acc) {
if (idx == array.length)
return acc;
return sum(array, idx+1, acc+array[idx]);
}
Call it like this:
int[] array = {1, 2, 3};
System.out.println(sum(array));
As you can see, there's no need to declare (static or instance) attributes, and no need to pass and modify mutable objects (lists, maps) - I'm not even using local variables, because all the required information needed to solve the problem is present as method parameters.
In the code in your question the v variable is supposed to do what the acc parameter is doing in my answer, namely: modifying an accumulated value each time the recursion is called. In the end, you just need to return the accumulated value from the helper function (which must not have a void return type) and that's how you'll get the value in foo().
A variable declared in a scope (for example method) is accessible only in this scope (e.g. not in another method).
If the information is relevant for the method only, keep the variable in the method. If the information is relevant for the whole object / class state, keep it a class member (static/non static).
For example:
public void someRecursiveMethod(int num) {
while (num < 10) {
num++;
someRecursiveMethod(num);
System.out.println("Current num = " + num);
}
}
You can create a new class (yuck), or pass the variable as a parameter and return it in fooHelper.
Why not make it an instance variable(not necessarily static)...??
public class Recursive {
int v = 0;
public void foo(){
fooHelper(2);
System.out.println(v);
}
public void fooHelper(int depth){
v++;
if(depth-1!=0)//Added this because I was getting an StackOverflowError
fooHelper(depth-1);
}
public static void main(String[] args) {
Recursive r = new Recursive();
r.foo();
}
}
You could return a list or a similar data structure:
public List<Integer> fooHelper( int v, int depth ){
if( depth == 0 ) return new ArrayList();
v++;
List<Integer> result = fooHelper( v, depth-1 );
result.add( new Integer(v) );
return result;
}
Because the variable v is of primitive type, changes made to it will not be visible outside the function scope. You could declare the variable v inside a class, say State and pass the state object into the recursive function to get the required effect.
public void foo(){
State state = new State();
fooHelper(state, 2);
}
public void fooHelper(State state, int depth){
state.v++;
fooHelper(state, depth-1);
}
class State {
int v;
}
Hope it helps.
You can pass an object to store the update for each recursive call. Something like the one below.
public static void fooHelper(int depth, HashMap map){
map.put(depth, "Call " + depth);
if (depth > 0)
{
fooHelper(depth-1, map);
}
return;
}
I think this is called memoization. It looks like
class Fibonacci
{
public Map < Integer , Integer > memorized = new HashMap < > ( ) ;
public int fib ( int n )
{
if ( memoized . containsKey ( n ) )
{
return memoized . get ( n ) ;
}
else
{
int fib = // calculate recursively
memoized . put ( n , fib ) ;
return fib ;
}
}
}
You should be able to get decent (not optimal) performance out of this algorithm. The primary reason that the recursive fibonacci algorithm has horrible performance is b/c it is repeatedly calculating the same values. With recursion+memoization it never calculates any value more than once.
Thanks to #Aristide for pointing out the subtle difference between memorization and memoization.

Categories