Assign an Object to a String - java

I am writing a program that generates a maze and then finds a path. I store all my moves into a stack called visitStack (if I move north, I store "N" into it, if Northeast then "NE", on and on). For part of my backtracking I need to be able to take the data from the stack and reverse my steps if I hit a dead end, but I've hit a snag here.
I need to assign a value popped from a stack to a String variable, but I always get a compiler error. I've tried using toString, instantiating the String as an object with the popped stack value as the parameter, and still can't get it. I've been on this for about an hour. Here is the code and error message.
String direction = visitStack.pop();

Assuming that you are using java.util.Stack I suspect that you didn't describe what type of elements it should store, which is why compiler sees return type of pop as Object (common ancestor of all types).
Also assuming that stack should store only String elements it should be declared as
Stack<String> visitStack = new Stack<String>();
Now compiler should see return type of pop() as String which will allow you to store its result in other String type reference
String direction = visitStack.pop();
Above solution is preferred when you are sure that stack can contain only strings, but if there are some other elements you will need to either explicitly cast returned object to String (if you are sure that it will be instance of String) like
String direction = (String) visitStack.pop();
or if you are not sure what object will be returned calling toString() method to get its string representation:
String direction = visitStack.pop().toString();

If you define your stack as Stack<String>, pop() will return a String, and you won't need to mess around with casting. If you cannot, for some reason, and you're positive the object being popped is a String, you can cast it explicitly:
String direction = (String)visitStack.pop();

Since you are using a limited number of possible values you shloud use ENUMS for type Safety.
Use :
Stack<Direction> visitStack=new Stack<>();
visitStack.push(Direction.EAST);
Direction dir=visitStack.peek();
String dir2=visitStack.pop().toString();
System.out.println(dir);
System.out.println(dir2);
your Direction should look like:
public enum Direction {
North("N"), NORTH_WEST("NW"), NORTH_EAST("NE"), EAST("E")
, SOUTH_EAST("SE"), SOUTH("S"), SOUTH_WEST("SW"), WEST("W");
private String shortName;
private Direction(String shortName) {
this.shortName = shortName;
}
#Override
public String toString() {
return this.shortName;
}
}

Related

How to get the values of specific fields in a Map<String, Object>

I have something like:
Map<String, Object> hashMap;
When I do something like:
hashMap.get("binary"), I get value as: {size=5642, name=abc}
Here key is binary and value is an Object of Type Object and is {size=5642, name=abc}
Note the values dont belong to a particular class.
In Python I can do something like hashMap["binary"]["size"], was wondering what would be the equivalent in java
How do I get the value of size directly without parsing the above string?
The value is not of Type Object, but of some type that extends from Object (in java everything extends Object implicitly). Let's call it "X"
Now, it doesn't work like python because unlike python java doesn't have that dynamic nature.
{size=5642, name=abc} is probably a string representation of that type X. This is what you see in a debugger or maybe when trying to print the value on console with System.out.println or something.
Now first of all figure out which type is it:
Object value = hashMap.get("binary")
System.out.println(value.getClass().getName());
It will print the class name
Then check the source of that class, probably it looks like this:
public class X {
private final int size;
private final String name;
... // constructor, other stuff maybe
// these are called "getters" in java world
public int getSize() {return size;}
public String getName() {return name;}
}
From that point you have 2 ways to get the size:
Object value = hashMap.get("binary");
int size = ((X)value).getSize(); // This is called downcasting
The drawback of this method is that you don't utilize the power of generics
So the better option is a refactoring if its possible of course:
Map<String, X> hashMap = ...
X value = hashMap.get("binary");
value.getSize();
One final note:
If it happens that the value is of type String, you won't be able to get the size other than parsing the value with regular expression or something. In this case consider a refactoring as a better option.

In Java, how do you enforce Stack.pop() as a parameter?

I have two stacks.
I want to be able to push any element onto one, but only if it was popped off the other.
Instead of My current function looks like this:
public void pushValue(int poppedValue) {
Stack.push(value)
}
I want the function to look something like this:
public void pushValue(pop() poppedValue) {
Stack.push(value)
}
How could I set the pop() function as a parameter, instead of an int?
In other words, how can I set the parameter to only accept a value that was popped from somewhere?
There is no way in Java to express that constraint. (Or in any other language, AFAIK)
(IMO) the best you can do is to pass the second Stack as an argument to the first one and make the first one responsible for popping a value; e.g.
public class Stack {
...
public int transferValue(Stack source) {
int res = source.pop(); // throws exception if source is empty
this.push(value);
return res;
}
}
This leaves you with problems regarding push:
Do you remove it entirely from the Stack API? If so, how do the elements get onto the source stack?
Do you split the Stack API into Stack and StackWithoutPush? If yes, which is the super-class / super-interface? Neither alternative is perfect. Either way, the subclass violates the contract of the superclass in some sense. (C.f. the problem of List versus UnmodifiableList APIs.)
Your syntax isn't possible, but you could make the second stack a member field and then push iff the value is present when you peek at the second stack (through the field).
private Stack otherStack = null; // <-- set this somehow (constructor?), or pass it.
public void pushValue(int newValue) {
if (otherStack != null && otherStack.peek() == newValue) {
Stack.push(newValue); // <-- please observe naming conventions (stack)
}
}
Then, pop() the value. Basically, peek, push and then pop.

Is there a way to match a String with a method?

As far as I've researched, there's no way to match a String with a variable. probably I'm using the wrong word, here's what I mean by matching:
String grade="a";
double a=4.0;
And there's no way to associate the value of String grade with double a.
Similarly, what I want to do is associating value of a String with a method. Maybe I'm on the wrong track, let me briefly explain what I'm trying to achieve:
In the class player, there's a String name() method that returns This.name. There's no graphical design, and the only way for user to communicate with the program is typing. Basically, when person types name, I want name method to be ran. I'm pretty new, and the only way I can think of doing it is using a bunch of if statements, and adding another if statement for each method I add does not sound right to me.
Note: The reason I need String to be associated is because I'm going to use javax.swing.JTextArea to get input from the user, which returns String.
Thanks in advance
Yes. It's called a Map.
Here's some sample code of how to use one:
Map<String, Double> map = new HashMap<>();
map.put("grade", 4.0);
double a = map.get("grade");
If you want to store a variety of value types use Map<String, Object>, but you'll have to make unsafe casts when retrieving and using the values returned from get().
Java is not a dynamic interpreted language like Python or Perl.
To associate arbitrary strings with values you should use a Map<String,ValueClass> where ValueClass is the value to associate, such as Integer, Float, BigDecimal or your own value class.
Because grades are usually fixed from A to F, I would use an enum to map each grade to a numeric value:
enum Grade {
A(4.0), B(3.0) // etc...
private double val;
private Grade(double val) {
this.val = val;
}
public double getVal() {
return val;
}
}
Then use Grade.A.getVal() when you need the numeric value of the A grade.

What does it mean to return an enum with the same name as the string parameter?

My professor wants us to make an enum called MedicalSpecialty, with GENERAL_MEDICINE, PEDIATRICS, and ONCOLOGY as members of the enumeration (so far so good).
Then he wants us to define a method called getFromString inside the MedicalSpecialty enum "that takes a String parameter and returns a MedicalSpecialty with the same name as the String parameter"
I'm not sure what he means, but then he says:
"Hint: use the toString() method from the MedicalSpecialty enum to perform your checks"
I'm not looking for a solution, but rather an explanation of what he is asking, if anyone understands. Is the getFromString method meant to take in a String like "general_medicine" and then output "GENERAL_MEDICINE" as type MedicalSpecialty? That seems useless and probably wrong...
Any help would be appreciated!
You have the right idea. Think of it this way:
Suppose you are designing a system that works with components that function across the globe and you use the internet to communicate between them. A component in Europe, wants to request a new doctor of Oncology to be transferred from the US component. It can't send a MedicalSpeciality enum over the wire, so instead it sends a String, e.g. "Oncology". Now, in the code of your US component, you want to translate that piece of text to something that your US component system understand: the enum.
You need to write a method that takes the input String sent over the wire and returns the corresponding Enum value.
He means that valid input for your function will be the following:
"GENERAL_MEDICINE", "PEDIATRICS", "ONCOLOGY"
Your task is to convert the type String to the type Enum.
He probably wants you to show that you know how to loop through all the elements of an enum and compare each toString result to the passed in string.
You're right, that's not the best way to do it.
public enum Medicine {
GENERAL_MEDICINE("general_medicine"),
PEDIATRICS("pediatrics");
private final String value;
Medicine(String v) {
value = v;
}
public String value() {
return value;
}
public static Medicine fromString(String v) {
for (Medicine c : Medicine.values()) {
if (c.value.equals(v)) {
return c;
}
}
throw new IllegalArgumentException(v);
}
}

When creating methods and passing objects as parameters, are they copied or referenced? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is Java pass by reference?
see example below... need java.io library to run...
public class BlankClass extends ConsoleProgram {
public void run() {
while(true) {
setFont("London-24");
String name = readLine("Type a name: ");
fixName(name);
/* I know that the way this is written doesn't make sense and that println(fixName(name))
* is the right way. However, I thought that when objects then the method is using the object
* (in this case a string) and not a copy of it. In other words, it is referenced.
* So if it is referenced why isn't it printing out Steven when I give it STEVEN.
*/
//println(fixName(name); this is removed to show the question.
println(name);
}
}
private String fixName(String name) {
char first = name.charAt(0);
first = Character.toUpperCase(first);
name = name.substring(1);
name = first + name.toLowerCase();
return name;
}
}
Java always passes parameters by value - but in the case of classes/objects, the value that's passed is a reference, not an object itself.
What the type involved, the value of the argument expression is copied as the initial value of the parameter. Changes to the parameter variable itself are not seen by the caller, whereas changes to the object that the reference refers to will be seen.
For example, using StringBuilder (which is a mutable type):
public void foo(StringBuilder builder)
{
builder = new StringBuilder("Change to builder");
}
public void bar(StringBuilder builder)
{
builder.append(" - appended");
}
Now:
StringBuilder x = new StringBuilder("Original value");
foo(x);
System.out.println(x); // Still prints "Original value"
StringBuilder y = new StringBuilder("Original value 2");
bar(y);
System.out.println(y); // Prints "Original value 2 - appended"
Note that when I say "the value of the argument expression", that is never an object - it's either a primitive value, or a reference.
I like to think of an analogy with houses. Suppose you have a piece of paper (a variable) with directions to a house written on it. You call a method and use that variable as the argument - that creates a new piece of paper (the parameter) with the same directions on. If the method crosses out the original directions and replaces them with some other ones, that doesn't change the first piece of paper. On the other hand, if the method follows the directions and then paints the house red, then you would see that change if you followed the directions on the first piece of paper.
EDIT: To explain your original code... no objects are being copied, but the value of name in run is being copied into fixName. You're then changing the value of the parameter in fixName when you write this:
name = name.substring(1);
You're changing it again when you write:
name = first + name.toLowerCase();
Neither of these have changed the value of name in the calling code, which is still referring to the original string.
You're then returning the new string reference here:
return name;
but your calling code is completely ignoring it, because you've just written:
fixName(name);
One way to demonstrate what's happened is to use the return value in a new variable:
String fixedName = fixName(name);
Then you could print out name (which would show the original string) and fixedName (which would show the new one).
you pass a reference, so you work with the same string, BUT you return another string, because String in java is immutable - every operation (such as subString) produce new string and if you want to perform many operations on string (such as substring, replace etc.) use a StringBuffer or StringBuilder
This does not really answer your question, but you should avoid assigning parameters (like 'name' in this case), it can be handy at times but it is generally considered a bad practice because it often leads to unreadable and hard to maintain code.
In your case the variable is both a parameter and a local variable.
In Eclipse there is a warning you can activate for this in
Preferences->Java->Compiler->Errors/Warnings->Code style->Parameter assignment
I would recommend to set the parameter 'name' final in order to enforce this.
Return another String that is based on your 'name' String and name it properly.
The goal is that anyone reading your code should be able to quickly understand what is going on by elimination (the function is private, it is static, the parameter is final...). This excludes a lot of side effects.
Search for the concept of 'pure functions' on the web. Make the method static so the person reading your code knows that there are no side effects on the instance.
Here is the new version:
private static String fixName(final String name) {
final char firstCharOfName = Character.toUpperCase(name.charAt(0));
final String fixedName = firstCharOfName + name.substring(1).toLowerCase();
return fixedName;
}

Categories