Manipulating an object inside a method - java

I am trying to manipulate an object inside a method like this:
My class Problem:
public class TaxiProblem {
public Problem(final World world, final Agent agent) {
_world = world;
_world.setRandomAgent(_agentPlace);
}
private Place _agentPlace;
// Various other functions
}
and in the function .setRandomAgent() in the class World I am trying to manipulate the Place object in what I want it to be like this:
public void setRandomAgent(Place agentPlace) {
int rand = _random.nextInt(25);
agentPlace = _places.get(rand);
agentPlace.setHasAgent(true);
}
I basically want to grab a random Place from the List _places and have it in the variable agentPlace in .setRandomAgent() which in turn will have it in _agentPlace in the Problem class. I thought this would work since Java passes objects by reference in methods but it didn't and _agentPlace remains null.

By doing this
agentPlace = _places.get(rand);
you are overwriting the reference that was passed to the method and losing access to the object you want to alter.
In your setRandomAgent method, agentPlace is indeed a reference that points to your _agentPlace field, not the field itself. In the line I pasted above, what you do is make that reference point to a different object.

_agentPlace = _world.getRandomAgent();
public Place getRandomAgent() {
int rand = _random.nextInt(25);
Place agentPlace = _places.get(rand);
agentPlace.setHasAgent(true);
return agentPlace();
}
When you pass agentPlace to the method, you are creating a copy of the reference. So if you modify the object, then it would work when you return up the stack. But reassigning the variable makes you lose the object you were working with.

I suspect that your problem lies in the implementations as your understanding of pass by reference I believe is correct. The following code will produce the results you expect - That is, it will first print "Before change", then "I am changed!".
class Program
{
static void Main(string[] args)
{
var problem = new Problem();
}
}
public class Problem
{
public Problem()
{
var toChange = new ClassToChange();
toChange.ChangeMe = "Before change";
Console.WriteLine(toChange.ChangeMe);
var changer = new ClassThatChanges();
changer.ChangeSomething(toChange);
Console.WriteLine(toChange.ChangeMe);
Console.ReadLine();
}
}
public class ClassToChange
{
public string ChangeMe { get; set; }
}
public class ClassThatChanges
{
public void ChangeSomething(ClassToChange classToChange)
{
classToChange.ChangeMe = "I am changed!";
}
}

Related

How can I assign instance of a class from an array to a class initializer in java?

In a Android application I am making I have an array of instances of a certain class I made, and later in the program I need to use the getter and setter methods from that class on an instance of the class from the array. Do I need to assign the instance of the class from the array to a new class initializer? Here is some code to clear this up:
Class
public class ProfileInformation {
private String console;
private String gamertag;
public String getConsole() {
return console;
}
public void setConsole(String console) {
this.console = console;
}
public String getGamertag() {
return gamertag;
}
public void setGamertag(String gamertag) {
this.gamertag = gamertag;
}
}
Array
ArrayList<ProfileInformation> ProfTags = new ArrayList<>();
Some instances of ProfileInformation are then added to arraylist, and then I get one of the instances from the arraylist and try to use getGamertag() to set it to a string:
ProfileInformation profNew = ProfTags.get(ProfTags.size()-1);
String example = profNew.getGamertag();
The problem is example will equal null. Why is this?
First, an Arraylist is a List, try not to confuse that with actual arrays.
Do I need to assign the instance of the class from the array to a new class initializer?
You don't need to get an element out of the Arraylist, no. You can chain many methods together
String example = ProfTags.get(ProfTags.size()-1).getGamertag();
example will equal null. Why is this?
For the same reason any object is null... You never set it equal to anything else
This code runs on my laptop:
public static void main(String[] args) {
ArrayList<ProfileInformation> ProfTags = new ArrayList<>();
element = new ProfileInformation();
element.setGamertag("Actual Gamer tag value");
ProfTags.add(element);
ProfileInformation profNew = ProfTags.get(ProfTags.size()-1);
String example = profNew.getGamertag();
}
Output is:
Actual Gamer tag value
I guess you didn't call setGamertag(String).

Calling an array from a different class - Java

How can I access my array from a different class? I have 3 classes; Main (where I want to access the array from) FramePanel (my GUI and where the value from UserInputNum is taken from) and StoryArray (where my array is saved).
I need to access the array in the nested If loop in the Main class, this is because I want too save the specific array data to a string and eventually append it into a JTextArea.
Here are the two classes needed:
Main.java
public class Main
{
public static String UserInput;
public static int UserInputNum;
public static void main(String[] args)
{
FramePanel.main();
StoryArray.main();
UserInputNum = Integer.parseInt(UserInput);
if (UserInputNum >= 0)
{
if (UserInputNum <= 399)
{
StoryArray.storyLine[UserInputNum];
}
else
{
}
}
else
{
}
}
}
StoryArray.java
public class StoryArray
{
public static String storyLine[] = null ;
public String[] getStoryLine()
{
return storyLine;
}
public static void main()
{
//String[] storyLine;
storyLine = new String[399];
storyLine[0] ("1")
storyLine[1] ("2")
storyLine[2] ("3")
storyLine[3] ("4")
storyLine[4] ("5")
storyLine[5] ("6")
In another class you can call the array like this:
String value = StoryArray.storyLine[index];
As it is a static public field you can access it directly by StoryArray.storyLine. But as you have a getter ethod I would suggest to make this getter setter static and the array field private and access it through getter method like that: StoryArray.getStoryLine() (to see why read about encapsulation).
You also shouldn't start your class (main) name from lower case, here are standard coding conventions for java language: http://www.oracle.com/technetwork/java/codeconvtoc-136057.html
Once you've called StoryArray.main(), then you should be able to do StoryArray.storyLine[/*element id*/] = "whatever you want" to get or set any element in storyLine. Additionally, you aren't defining any default array values. In StoryArray.main(), you need to have lines of the form storyLine[n] = "n".

What is the best practice for the scope of variables in a class

My teachers source code was published and i was confused when i saw this:
New local variables where instantiated from a static variable, the variable was then used in a method and passed as an argument to another method, to then set its new value to the same static variable that the copy was based on. Since the scope of a static variable will be accessible throughout the class, why not access the static variable directly from every method within that class?
Why do this:
public class Calculator {
private JTextField displayText;
public void actionPerformed(ActionEvent e) {
String input = displayText.getText();
if (something == right) {
for (int i = 0; i < 10; i++) {
enterNumber(input);
}
}
}
public void enterNumber(String input) {
displayText.setText(input);
}
}
If you can just:
public class Calculator {
private JTextField displayText;
public void actionPerformed(ActionEvent e) {
if (something == right) {
for (int i = 0; i < 10; i++) {
enterNumber();
}
}
}
public void enterNumber() {
String localVar = "Kitten";
displayText.setText(localVar);
}
}
In this exact example you are right, there is no point in having a parameter in your enter number method.
but when you begin to work on more complex programs you start to notice that you end up using the same functionality over and over again, in which you can have a method with parameters, such that you can perform the same action with slight variation.
also it is easier to read for other people if you have a method with parameters, since all you have to do is say, "ok i call the method and send it blank, it sets the value to whatever i sent it.", instead of saying "ok i call the method, now lets see what the method does."
if your code works then it is not bad code. but if it works and is easy to read then it is good code.

How do I reference one method in another? And why am I only able to define a variable in an if statement once?

public void toggleoperator(View v){
ToggleButton oprtoggle = (ToggleButton) findViewById(R.id.operatortoggle);
boolean add = ((oprtoggle.isChecked()));
if (add){
oprtoggle.setTextOn("Add");
int x = 1;
} else {
oprtoggle.setTextOff("Subtract");
int x = -1;
}
public void sumNumbers(View v){
EditText input1 = (EditText) findViewById(R.id.input1);
int calc1 = Integer.parseInt(String.valueOf(input1.getText()));
EditText input2 = (EditText) findViewById(R.id.input2);
int calc2 = Integer.parseInt(String.valueOf(input2.getText()));
int totaladd = calc1 + calc2;
int totalsubtract = calc1 - calc2;
if (add) {
String result = String.valueOf(totaladd);
} else {
String result = String.valueOf(totalsubtract);
}
EditText output1 = (EditText)findViewById(R.id.output);
output1.setText(result);
}
I'm trying to get the above code to work. For one, I want to reference the boolean 'add' from the first method to the second method, how would I go about doing that? Also, I'm getting a 'Not a statement' error on this line
String result = String.valueOf(totalsubtract);
Help? And please explain too, otherwise I won't learn!
If you want to reference a method from another method you simply call the second method from the first one.
public void methodA(){
methodB();
Object o = new Object();
methodC(o);
}
public void methodB(){
//do something
}
public void methodC(Object o){
o.doSomething();
}
Fields in Java have something called scope. The scope of a local field, as in defined inside a method or a loop, is exhausted when the method or the loop is over.
If you want to make a field accessible to the whole Class, you need to define it outside methods, you do not need to initialize the field immediately, you can delegate it to constructor or methods.
public class Clazz{
public int i;
public Clazz(int i){
this.i = i;
}
public void setI(int i){
this.i = i;
}
}
If you're trying to access a variable in another method, it won't work because of "scope".
Basically, if you define a variable inside a method, it will only be available TO that method. One work around is to define the variables outside the method, so that all the methods in that class can access them. Another solution would be to "return" the variable, so that other methods can access them by calling your method.
I suggest reading this:http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
and this:http://java.about.com/od/s/g/Scope.htm
If you want your "add" boolean to be accessible from both methods, it should be created as a class variable, rather than a function variable OR it should be passed via parameters to the second function.
class Clazz {
//Declares the variable at class scope (this should be false by default)
boolean add;
//Sets the value of the "add" boolean
public void toggle () {
add = toggle.isChecked();
}
public void secondMethod () {
int diff = 0;
if (add) {
//make "diff" a positive value, based on what's entered.
} else {
//make "diff" a negative value, based on what's entered.
}
Display.setText(new String(diff));
}
}
I will not say that this is the nicest example code ever, however it is functional and SHOULD resolve your issues.
I would like to note, in addition, that it is trivial that the addition and subtraction both be done if only one of these is needed. This is why I had changed the way that the calculations come out.

How can I use the Command Pattern in Java like I do in C++?

I was working on a game recently in C++ where I implemented the Command Pattern to manage keyboard input to control a spaceship. When instantiating all the commands, I'd pass the spaceship pointer to each constructor so all commands were working with the same spaceship object.
This pattern made sense in C++ because you can pass by reference, but in Java everything is pass-by-value. If I tried to implement the same thing in Java, how would I have each command pointing to the same object?
In all the examples I've seen of the Command Pattern used in Java it makes no difference whether the member variables of each Command are copies or references.
Java does pass by value in all cases, however all 'non-primitive' types exist as references, so for types like String, List or Spaceship you're actually passing a reference around - the pass by value is because you're passing the reference by value. Which is a pretty confusing way of expressing it, I always felt.
Anyway, the upshot of it is that if you have a (hugely simplified) Command class
public class Command {
private Spaceship spaceship;
public Command(Spaceship ship) {
spaceship = ship;
}
}
And then you do this:
Spaceship ship = new Spaceship();
List<Command> ships = new List<Command>();
for (int i = 0; i < 40; i++) {
ships.add(new Command(ship));
}
then every single one of those Command objects has a reference to the same Spaceship object. Passing the reference by value does not cause a copy of the Spaceship object that the reference points to. However, if you were passing ints around, you would indeed be passing copies.
Just remember the distinction between primitive types like int, and object types like String and you'll be fine. It's helpful to remember that primitive type names begin with a lowercase letter (and can never be user-defined), while object types begin with a capital letter. All user-defined types are object types.
Thanks for your help guys. At the end of the day it came down to my complete misunderstanding about how Java works. I was under the impression (for some strange reason) that creating a Command and giving it my object meant that it received a copy instead of a reference to the original. If that was the case then calling .execute() in a Command would have had no effect on the object outside of the class.
Yet, I found that this was not the case after creating a small test:
Sprite.java:
public class Sprite {
private int x;
Sprite(int x) {
this.x = x;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
}
Command.java:
public interface Command {
void execute();
}
MoveLeftCommand.java:
public class MoveLeftCommand implements Command {
private Sprite s;
MoveLeftCommand(Sprite s) {
this.s = s;
}
public void execute() {
s.setX(s.getX() - 1);
}
}
MoveRightCommand.java:
public class MoveRightCommand implements Command {
private Sprite s;
MoveRightCommand(Sprite s) {
this.s = s;
}
public void execute() {
s.setX(s.getX() + 1);
}
}
Test.java:
import java.lang.*;
import java.util.*;
public class Test
{
public static void main(String[] args) {
Sprite mario = new Sprite(0);
Command command = null;
Map<String, Command> commands = new HashMap<String, Command>();
commands.put("a", new MoveLeftCommand(mario));
commands.put("d", new MoveRightCommand(mario));
// Test...
System.out.println(mario.getX()); // 0
command = (Command) commands.get("a");
command.execute();
System.out.println(mario.getX()); // -1
command.execute();
System.out.println(mario.getX()); // -2
command = (Command) commands.get("d");
command.execute();
System.out.println(mario.getX()); // -1
}
}
I correctly saw 0 -1 -2 -1 in the console, just as I would have in C++.
In java they passed "by value"... You pass real object that will implement an execute method. Sharing reference among different objects can be achieved by proper OO design or lookup method injection for common attribute. The Command pattern example was taken from wikipedia
/*the Command interface*/
public interface Command {
void execute();
}
/*the Invoker class*/
import java.util.List;
import java.util.ArrayList;
public class Switch {
private List<Command> history = new ArrayList<Command>();
public Switch() {
}
public void storeAndExecute(Command cmd) {
this.history.add(cmd); // optional
cmd.execute();
}
}
/*the Receiver class*/
public class Light {
public Light() {
}
public void turnOn() {
System.out.println("The light is on");
}
public void turnOff() {
System.out.println("The light is off");
}
}
/*the Command for turning on the light - ConcreteCommand #1*/
public class FlipUpCommand implements Command {
private Light theLight;
public FlipUpCommand(Light light) {
this.theLight = light;
}
public void execute(){
theLight.turnOn();
}
}
}
Since Java always does pass by value, you will need to do something mutable to pass through instead (pass a mutable object).
Consider this example:
In this agnostic language that supports pass-by-reference
string commandArg = "";
new StringCommand().execute(commandArg);
Console.write(commandArg);
And in StringCommand.execute(string arg), you have arg += "Hello World", then your output will be Hello World.
In Java, simply pass a StringBuilder as follows:
StringBuilder sb = new StringBuilder();
new StringCommand().execute(sb);
System.out.println(sb.toString());
where StringCommand.execute(StringBuilder sb) contains:
sb.append("Hello World");
The StringBuilder reference is passed by value in StringCommand.execute. In a nutshell, primitive types are passed by value and, for objects, the reference of the object is passed by value.
I hope this helps.

Categories