Changes being made to an object in Java - java

I have created a Compound class that holds the number of Carbon, Hydrogen, Oxygen, Nitrogen and it's bond count. I have a stack that holds these objects.
Initially the stack will start off at empty and I will pop that. Then I will apply addHydrogen function to it so it's Hydrogen will = 1, Oxygen=0, Nitrogen=0 and Carbon=0.
I then want to take the same object and apply the addCarbon function so that Hydogren will = 0, Oxygen=0, Nitrogren=0 and Carbon=1.
How can I write my program so I can use the same object but not with the changes I made from adding the Hydrogen? I know I could use some if cases initially but I don't think it will work because I will eventually start with a compound that has hydrogen=2, oxygen=2, Nitrogren=0, Carbon=1.
*I didn't include my constructors in the code, they just initialize everything to 0.
class compound {
int Hydrogen;
int Carbon;
int Nitrogen;
int Oxygen;
int bond;
public void addHydrogen(compound comp) {
Hydrogen++;
}
public void addCarbon(compound comp) {
Carbon++;
}
}
public static void main(String[] args) {
Compound a= new Compound();
a.addHydrogen(a);
a.addCarbon(a);
}

Your question isn't very clear, but one option you might wish to consider would be to make your object immutable - so you could never change the values within a single object, but you could instead make your addCarbon (etc) methods return a new object with appropriate new values in.
(Note that currently you're not using your parameters, which appear to have the wrong case anyway...)
Sample code:
public class Compound {
private final int hydrogen;
private final int carbon;
private final int nitrogen;
private final int oxygen;
public Compound(int hydrogen, int carbon, int nitrogen, int oxygen) {
this.hydrogen = hydrogen;
this.carbon = hydrogen;
this.nitrogen = nitrogen;
this.oxygen = oxygen;
}
public int getHydrogen() {
return hydrogen;
}
// ... etc for the other getters
public Compound plusHydrogen() {
return new Compound(hydrogen + 1, carbon, nitrogen, oxygen);
}
// etc for the other plus calls
}
Note that I've called the methods plusHydrogen etc to make it clear that they're not mutating the existing object, but returning a new one.
Then you can have:
Compound base = new Compound(0, 0, 0, 0);
Compound withHydrogen = base.plusHydrogen();
Compound withCarbon = base.plusCarbon();
// whatever

Related

Can we use Setter Method in java to perform operations?

Is setter method only use to assigning values? or can we perform operations in it. Here in this code the commented part is giving me correct output but while using set and get I am getting output as 0.
I want to avoid calling totalMarksOfStudent() method again and again because it have 5 parameters which I dont want to give again and again. So what is the way to return totalMarksStudent in another class without calling totalMarksOfStudent().
int totalMarksStudent = 0;
public void setMarks(int englishMarks, int mathsMarks, int physicsMarks, int chemistryMarks, int csMarks) {
totalMarksStudent = englishMarks + mathsMarks + physicsMarks + chemistryMarks + csMarks;
}
public int getMarks(){
return totalMarksStudent;
}
// public int totalMarksOfStudent(int englishMarks, int mathsMarks, int physicsMarks, int chemistryMarks, int csMarks) {
// totalMarksStudent = englishMarks + mathsMarks + physicsMarks + chemistryMarks + csMarks;
// return totalMarksStudent;
}
public String displayTotalMarks() {
String totalMarks1 = "Name " + name + "\tRoll No " + rollNo + "\tTotal Marks " + getMarks();//totalMarksOfStudent(englishMarks, mathsMarks, physicsMarks, chemistryMarks, csMarks);
return totalMarks1;
}
Better to avoid that...
I think it's better to have some fields like your parameters in setMarks (englishMarks , mathsMarks , ...) , and give value to them in constructor or setter methods. Also it's better to have a method named something like calculateTotalMarks , and call it without any parameters whenever you need it. Remember that there will be no problem to have operations in setter methods but usually and for better designed program we avoid that. Methods should do the thing their name says : for example , setter just for assigning , getter just for accessing values , calculateTotalMarks for calculating the total marks and so on ...
setter method is usually used to assigning values. It is promise.
You can reduce parameters by using Object
I recommend to make object of MarksStudent. because common attribute can bind to one class. It make understand easily code
for example
// Java is object-oriented language
class marksStudents {
private int english;
private int math;
private int physics;
private int chemistry;
private int cs;
//getMethods is Abbreviation
public int getTotal() {
return english+math+physics+chemistry+cs;
}
//setMethods
public void setEnglish(int english) {
this.english = english;
}
public void setMath(int math) {
this.math = math;
}
public void setPhysics(int physics) {
this.physics = physics;
}
public void setChemistry(int chemistry) {
this.chemistry = chemistry;
}
public void setCs(int cs) {
this.cs = cs;
}
}
To execute
public class Main{
public static void main(String[] args) {
// You can make object marksStudents of studentsA
marksStudents studentsA = new marksStudents();
studentsA.setChemistry(20);
studentsA.setEnglish(30);
studentsA.setMath(40);
studentsA.setCs(50);
studentsA.setPhysics(60);
//200
System.out.println(studentsA.getTotal());
// You can make object marksStudents of studentsB too
marksStudents studentsB = new marksStudents();
studentsB.setChemistry(10);
studentsB.setEnglish(10);
studentsB.setMath(10);
studentsB.setCs(10);
studentsB.setPhysics(10);
//50
System.out.println(studentsB.getTotal());
}
}
The getter/setter method is only a practice. Not bad practice - it just defines a class, whose instances for the external world are handled by a list of independent values. Using them makes your code better comprehensible and easy to understand, what is it doing.
So it is no problem to make other operations with it, in general.
Some frameworks like to use reflection to use getters/setters and also reach the variables directly in them. In these cases, doing any different in the getters/setters than reading/writing the private members is no wise idea. Sometimes you can use a little bit of api/impl interface trickery to handle this problem.

Getting a parameter's value change to persist after function ending in Java [duplicate]

This question already has answers here:
Java : Best way to pass int by reference
(7 answers)
Closed 5 years ago.
I have a program which is meant to be a client/server game question game. I've made it as far as accounting various cases of the client/server sending a termination command for the end of the game.
Now, my issue is that I have a set of primitive int points, attempts, correct which are read by the client from the server in a String as below:
N.B. I do know that Java functions pass parameters by value, not reference, and that assigning the value inside of the function will not change the value of the original.
int points = accepted = correct = 0;
String inbound = check (inbound, points, accepted, correct);
System.out.println(points); // Displays value of 0, when expecting > 0
private static String check (String str, int points, int attempts, int correct) {
// Expect Q QuestionString
if (str.substring(0,1).equals("Q")) {
//System.out.println("This is the question.");
return str.substring(2, str.length());
}
String[] input = str.split(" ");
// Expect EX # # #
if (input[0].contains("EX")) {
points = Integer.parseInt(input[1]);
attempts = Integer.parseInt(input[2]);
correct = Integer.parseInt(input[3]);
return "EX";
}
// Expected strings: Correct..., Incorrect.
return str;
}
I am unsure how to workaround this issue without jeopardizing encapsulation or hindering other concepts.
Create a wrapper class to contain those three integer parameters then simply pass an instance of that wrapper to the check method and then modify its contents within the method.
example:
public class Wrapper
{
private int points;
private int attempts;
private int correct;
public int getPoints() {
return points;
}
public void setPoints(int points) {
this.points = points;
}
public int getAttempts() {
return attempts;
}
public void setAttempts(int attempts) {
this.attempts = attempts;
}
public int getCorrect() {
return correct;
}
public void setCorrect(int correct) {
this.correct = correct;
}
}
thus the first part of your code will become:
Wrapper wrapper = new Wrapper();
String inbound = check (inbound, wrapper);
System.out.println(wrapper.getPoints());
and your check method becomes:
private static String check (String str, Wrapper wrapper) {
...
...
if (input[0].contains("EX")) {
wrapper.setPoints(Integer.parseInt(input[1]));
wrapper.setAttempts(Integer.parseInt(input[2]));
wrapper.setCorrect(Integer.parseInt(input[3]));
return "EX";
}
...
...
}

Dealing with ArrayList and pass by reference

I'm using a arraylist to add states(the board state for the 8 puzzle). My problem is when I get the children of the state it changes the values stored in my array list. I'm assuming this is because ArrayList just stores pointers to the objects and not the values themselves. In order to fix this I create a new object every time before I store it into the ArrayList but I'm still having the same problem.
I will also try to follow naming conventions more often thanks for the tip.
private ArrayList<int[][]>VisitedBoard;
if(RuleNumber ==2){
//Here is my problem. This will change what is stored in VistedBoards
NextState = new State(FireRule.Rule2(WM.get_Board()));//Fire Rule
for(int j=0;j<VisitedBoards.size();j++){
//Meaning this will always be true
if(Arrays.equals(VisitedBoards.get(j), NextState.get_Board())){
Loop =true; //Loop to previous state
}
if(j==VisitedBoards.size()-1 && Loop ==false){ //If the next state is not any previously visited
NotALoop =true;
VisitedBoards.add(NextState.get_Board());
WM.set_Board(NextState.get_Board());
}
}
}
public int[][] Rule2(int [][] Board){//The FireRule Class
Find_BlankLocation(Board);
int temp;
State NewState;
temp = Board[BlankLocation[0]-1][BlankLocation[1]];
Board[BlankLocation[0]-1][BlankLocation[1]] = 0;
Board[BlankLocation[0]][BlankLocation[1]] = temp;
NewState = new State(Board);
return Board;
}
public class State { //State class
private int[][] Board;
private int[][] Goal;
private Boolean GoalFound;
public State(int[][] Start, int[][] goal){
Board = Start;
Goal = goal;
GoalFound=false;
}
public State(int[][] NewState){
Board=NewState;
}
public int[][] get_Goal(){
return Goal;
}
public int[][] get_Board(){
return Board;
}
public void set_Board(int[][] board){
Board = board;
}
public Boolean get_GoalFound(){
return GoalFound;
}
}
Containers like ArrayList work the same in all languages: they are called data structures because they organize storage/retrieval of objects. Obviously they don't store the fields of the objects themselves.
Trying to interpret your problem, maybe you don't want to share the boards between the list of visitedBoards and WM (whatever it means...). Then simply implement get_Board() to return a copy of the array instead of the Board object itself:
public int[][] get_Board(int[][] src) {
int[][] dst = new int[src.length][src[0].length];
for (int i = 0; i < src.length; i++) {
System.arraycopy(src[i], 0, dst[i], 0, src[i].length);
}
return dst;return dst;
}
Beside this, as others already told you, you'd really better to adopt the standard Java naming conventions, use meaningful names, and encapsulate your x, y and int[][] in real application classes.
Presumably, the new State object contains a pointer to the same arrayList as before. You'll want to manually copy the array out to a new one (a "deep clone" or "deep copy" as it is called). You might find this useful: Deep cloning multidimensional arrays in Java...?
Every time you create a new instance of State, you pass it the same array (whatever is returned by WM.get_Board()).
You then add that same array to VisitedBoards when you call VisitedBoards.add().
The fact that you're creating new State objects is irrelevant, because only the return value of NextState.get_Board() gets added to the list.
As a result, the list VisitedBoards always contains several references to the exact same array.
As Raffaele has suggested, you'll be fine if you make sure get_Board() returns a copy of the array in stead of a reference to the original (assuming that doesn't mess up logic that exists elsewhere).
The main thing I learned from this question is how important it is to follow naming conventions.
Your unconventional capitalization has made me dizzy!
Following these rules will make it much easier for others to understand your Java code:
class names should be capitalized (ie PascalCase)
variable names should be lowercase (ie camelCase)
do not use underscores in method names, class names, or variable names (they should only be used for constants)
always use meaningful names when possible
My advice is to create your own container object for their 2D array and implement deep copying.
For example:
package netbeans;
import java.util.Arrays;
public class Container
implements Cloneable
{
private int [] _data;
private int _sx;
private int _sy;
public int get(int x, int y)
{
try { return this._data[y*this._sx+x]; }
catch (Exception e) { throw new ArrayIndexOutOfBoundsException(); }
}
public void set(int x, int y, int value)
{
try { this._data[y*this._sx+x] = value; }
catch (Exception e) { throw new ArrayIndexOutOfBoundsException(); }
}
public Object Clone() { return new Container(this); }
public Container(int sizeX, int sizeY, int [] data)
{
this._sx = sizeX;
this._sy = sizeY;
this._data = data;
}
public Container(Container cont)
{
this._data = Arrays.copyOf(cont._data, cont._data.length);
}
}

Is it possible to return more than one value from a method in Java? [duplicate]

This question already has answers here:
How to return multiple objects from a Java method?
(25 answers)
Closed 7 years ago.
I am using a simulator to play craps and I am trying to return two values from the same method (or rather I would like to).
When I wrote my return statement I simply tried putting "&" which compiled and runs properly; but I have no way of accessing the second returned value.
public static int crapsGame(){
int myPoint;
int gameStatus = rollagain;
int d1,d2;
int rolls=1;
d1 = rollDice();
d2 = rollDice();
switch ( d1+d2 ) {
case 7:
case 11:
gameStatus = win;
break;
case 2:
case 3:
case 12:
gameStatus = loss;
break;
default:
myPoint = d1+d2;
do {
d1=rollDice();
d2=rollDice();
rolls++;
if ( d1+d2 == myPoint )
gameStatus = win;
else if ( d1+d2 == 7 )
gameStatus = loss;
} while (gameStatus == rollagain);
} // end of switch
return gameStatus & rolls;
}
When I return the value as:
gameStatus=crapsGame();
It appropriately sets the varaible to win or lose but if I try something as simple as following that statement with:
rolls=crapsGame();
It is assigned the same value as gamestatus...a 0 or a 1 (win or lose).
Any way that I can access the second returned value? Or is there a completely different way to go about it?
Create your own value holder object to hold both values, then return it.
return new ValueHolder(gameStatus, rolls);
It's possible to return an array with multiple values, but that's cryptic and it does nothing for readability. It's much easier to understand what this means...
valueHolder.getGameStatus()
than what this means.
intArray[0]
returning gameStatus & rolls means "return the bitwise and of gameStatus and rolls" which probably is not what you want
you have some options here:
return an array
create a class that represents the response with a property for each value and return an instance
use one of the many java collections to return the values (probably lists or maps)
You can return an array of values or a Collection of values.
Is it possible to return more than one value from a method in Java?
No it is not. Java allows only one value to be returned. This restriction is hard-wired into the language.
However, there are a few approaches to deal with this restriction:
Write a light-weight "holder" class with fields for the multiple values you want to return, and create and return an instance of that class.
Return a Map containing the values. The problem with this (and the next) approach is that you are straying into an area that requires runtime type checking ... and that can lead to fragility.
Return an array containing the values. The array has to have a base type that will accommodate the types of all of the values.
If this is a method on an object, then add some fields on the same object and methods that allow the caller to pick up "auxiliary results" from the last call. (For example, the JDBC ResultSet class does this to allow a client to determine if the value just retrieved was a NULL.) The problem is that this makes the class non-reentrant at the instance level.
(You could even return extra results in statics, but it is a really bad idea. It makes the class non-reentrant across all instances, not to mention all of the other badnesses associated with misused statics.)
Of these, the first option is the cleanest. If you are worried about the overhead of creating holder instances, etc, you could consider reusing the instances; e.g. have the caller pass an existing "holder" to the called method into which the results should be placed.
The best practice for an OOP approach is to return an Object. An object that contains all the values you want.
Example:
class Main {
public static void main(String[] args) {
MyResponse response = requestResponse();
System.out.println( response.toString() );
}
private static MyResponse requestResponse() {
return new MyResponse( "this is first arg", "this is second arg" );
}
}
class MyResponse {
private String x, y;
public MyResponse( String x, String y ) {
this.x = x;
this.y = y;
}
#Override
public String toString() {
return "x: " + x + "\t y: " + y;
}
}
If you want an even more scalable approach then you have to use JSON responses. (let me know if you want an example with JSON too)
You can following ways to do this:
Use a Container class, for example
public class GameStatusAndRolls {
String gameStatus;
String rolls;
... // constructor and getter/setter
}
public static GameStatusAndRolls crapsGame(String gameStatus, String rolls) {
return new GameStatusAndRolls(gameStatus, rolls);
}
public static void main(String[] args) {
...
GameStatusAndRolls gameStatusAndRolls = crapsGame(gameStatus, rolls);
gameStatusAndRolls.getGameStatus();
Use List or an array, for example
public static List<Integer> crapsGame(String gameStatus, String rolls) {
return Arrays.asList(gameStatus, rolls);
}
private static final int GAME_STATUS = 0;
private static final int ROOLS = 0;
public static void main(String[] args) {
...
List<Integer> list = crapsGame(gameStatus, rolls);
... list.get(0)...list.get(GAME_STATUS);
... list.get(1)...list.get(ROOLS);
or
public static String[] crapsGame(String gameStatus, String rolls) {
return new String[] {gameStatus, rolls};
}
private static final int GAME_STATUS = 0;
private static final int ROOLS = 0;
public static void main(String[] args) {
...
String[] array = crapsGame(gameStatus, rolls);
... array[0]...array[GAME_STATUS];
... array[1]...array[ROOLS];
Use Map, for example
public static Map<String, String> crapsGame(String gameStatus, String rolls) {
Map<String, String> result = new HashMap<>(2);
result.put("gameStatus", gameStatus);
result.put("rolls", rolls);
return result;
}
public static void main(String[] args) {
...
Map map = crapsGame(gameStatus, rolls);
... map.get("gameStatus")...map.get("rolls");

Java True Global Variables (Eclipse for Android)

This should be relatively straight forward however I'm being swamped in SQL information whenever I search for help with this.
Basically I have 3 classes and they each generate a number and I want to get the total number at the end. Is there a way to make a variable which all 3 classes can add to without generating a SQLite Database?
example
Page1.java creates 5 -> adds to Total
Page2.java creates 12 -> adds to Total
Page3.java creates 10 -> adds to Total
Page4.java opens total
Like I said, its likely a simple problem but SQLite is dominating my searches.
Hope you can help, Thanks.
You can use a static variable for that.
If you don't care about encapsulation you could even use one single public static variable for this purpose.
Example:
private static int mCounter = 0;
public static void addToCounter(int i)
{
mCounter += i;
}
public static int getCount()
{
return mCounter;
}
What you could do would be to have a private value, say, private int count in each of your class and its respective getter. You would then also have a method in each class, say, public void doSomething(){... count = ...}.
Once you have all these, in Page4 you could do something like:
public class Page4
{
Page1 pg1 = new Page1();
Page2 pg2 = new Page2();
Page3 pg3 = new Page3();
pg1.doSomething();
pg2.doSomething();
pg3.doSomething();
int total = pg1.getCount() + pg2.getCount() + pg3.getCount();
}
On the other hand, you could pass in an integer variable to the class which gets modified and passed on to the next class.
You could also pass in a reference to some class which contains the actual counter, and once that each class (Page1, Page2...) has finished doing what it needs it would simply reference that class and update the value itself.
It's not that clear how you call your classes.
However if you have just 3 simple classes and one place to call the classes you could pass your variable between the classes and add the values to it.
public class Page1 {
public void addToVariable(int var) {
var = var + 5;
}
}
public class Page2 {
public void addToVariable(int var) {
var = var + 12;
}
}
...
And then call the class methods with your variable:
int yourVariable = 0;
Page1 p1 = new Page1();
Page2 p2 = new Page2();
p1.addToVariable(yourVariable);
p2.addToVariable(yourVariable);
yourVariable will hold the total you're looking for.

Categories

Resources