JAVA trying to find positions of the year. Not Working [duplicate] - java

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 5 years ago.
I have a small program that reads a json file that gives the
weather, time, temp, wind, ect. I need to calculate the average
tempature for 2009 through 2015. The years are in an array, and are in
length, around 60k. I am trying to write a small loop that will first
find the position of the first instance of the year 2009 and then
the last instance of the year 2009. Then I can run my
average temp loop through that, but I am running into an issue as seen
below.
place will be the index of the array. However, no matter how I run my
code, it always equals -1, rather than giving me the position of
the index in the array. Both arguments in the if statements are
strings.
So what am I doing wrong?
String twozerozeronine = "2009";
int place = -1;
for (int a = 0; a < years.size(); a++){
if (years.get(a) == twozerozeronine){
place = 1;
break;
}
}
System.out.println(place);

years.get(a) == twozerozeronine
checks whether the object on the left side of the operator and the object on the right side of the operator are the very same. In your case they might be similar, but will never be the very same.
You will need to check whether they are similar instead:
years.get(a).equals(twozerozeronine)

You can use equals() method to compare the value of the Strings.
Like: if ( years.get( a ).equals( twozerozeronine ) ){
The == operator compares the Object references (in your case, both are not equal) whereas equals() method compares the actual string values (in your case, the string values are "2009").

Related

hashmap.get() == operator returning false

I'm working on the following problem:
Gary is an avid hiker. He tracks his hikes meticulously, paying close attention to small details like topography. During his last hike he took exactly n steps.
For every step he took, he noted if it was an uphill, U, or a downhill, D step. Gary's hikes start and end at sea level and each step up or down represents a 1 unit change in altitude. We define the following terms:
A mountain is a sequence of consecutive steps above sea level, starting with a step up from sea level and ending with a step down to sea level.
A valley is a sequence of consecutive steps below sea level, starting with a step down from sea level and ending with a step up to sea level.
Given Gary's sequence of up and down steps during his last hike, find and print the number of valleys he walked through.
For example, if Gary's path is s = [DDUUUUDD], he first enters a valley 2 units deep. Then he climbs out an up onto a mountain 2 units high. Finally, he returns to sea level and ends his hike.
Function Description
Complete the countingValleys function in the editor below. It must return an integer that denotes the number of valleys Gary traversed.
countingValleys has the following parameter(s):
n: the number of steps Gary takes
s: a string describing his path
Input Format
The first line contains an integer , the number of steps in Gary's hike.
The second line contains a single string , of characters that describe his path.
Output Format
Print a single integer that denotes the number of valleys Gary walked through during his hike.
Sample Input
8
UDDDUDUU
Sample Output
1
Below is my implementation in java. It works for the small test cases but not for the big ones.
static int countingValleys(int n, String s) {
//Use a hashmap to keep track of the number of moves.
HashMap<Character,Integer> map = new HashMap();
boolean sea = true;//check if we are at sea level
//if both D and U have the same total no, we are at sea level.
map.put('D',0);
map.put('U',0);
int valleys = 0;//count num of valleys
for(int i = 0; i < n; i++){
char key = s.charAt(i);
//check if we are at sea level
if(map.get('D') == map.get('U')){//<--PROBLEM
sea = true;
}
else
sea = false;
if(sea == true && key == 'D'){//if we are at sea level and our next key is D, we have a valley
valleys += 1;
}
map.put(key,map.get(key) + 1);//add move and update our hashmap
}
return valleys;
}
The problem seems to be at "if(map.get('D') == map.get('U'))", it seems to be returning false for big numbers, can someone tell me why? It works if I assign each map.get() to a variable and compare the variables instead.
I also wrote the exact same thing in javascript using the "new Object()" type and it passed all the test cases, but it is not working in java with hashmap, why is that?
link to original problem - https://www.hackerrank.com/challenges/counting-valleys/problem?h_l=interview&playlist_slugs%5B%5D=interview-preparation-kit&playlist_slugs%5B%5D=warmup
First, as mentioned in other answer, use .equals() instead of == in this case. An even better approach is, you don't even need to use a Map. Just one integer will be good enough.
As your question is ...returning false for big numbers, can someone tell me why?
Here is the reason.
There are several things you need to understand
1. Types of variable
First, you need to know there are two types of variable in Java: Primitive and Reference.
An integer is usually a Primitive, so the variable itself is the integer value: int a = 1234; : a itself is having value 1234.
To compare primitive variable, you should use ==
For reference type, variable itself is a "pointer". In Java there are Wrapper Classes for primitives. For example, Integer is the wrapper for int. So in Integer a = new Integer(1234);, a is not containing value of 1234. It is a pointer pointing to an Integer object reference. Using == on reference type variables does not compare the content, but only check if the pointer value is the same (i.e. check if they point to same object instance)
2. Autoboxing
Starting from Java 1.5 (iirc), there is a feature called auto-boxing (and unboxing), which ease programmer in converting between primitive types and their corresponding wrapper.
In the past, you need to do something like this:
int a = 1234;
Integer intWrapper = new Integer(a);
int b = intWrapper.intValue();
With autoboxing, you just need to write:
int a = 1234;
Integer intWrapper = a;
int b = intWrapper;
And compiler is going to convert it to:
int a = 1234;
Integer intWrapper = Integer.valueOf(a);
int b = intWrapper.intValue();
So far so good?
Final Answer
So the reason why your code works with small number is:
Integer.valueOf() is caching frequently-used value. From API doc:
public static Integer valueOf(int i)
Returns an Integer instance representing the specified int value. If a new Integer instance is not required, this method should generally be used in preference to the constructor Integer(int), as this method is likely to yield significantly better space and time performance by caching frequently requested values. This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.
Because it is caching the wrappers, therefore if you are doing map.put(key,map.get(key) + 1), result of get(key) + 1, which is an int, when converting to Integer and if it is a small number, will be a same instance of Integer for same int value. That means, == still works (as variables are pointing to same Integer). However if it is a not-cached number, every invocation will be a different instance, and == will not work (as variables are pointing to different instances of Integer, though the value in the Integer instances are the same)
Suggestion to your algorithm, though a bit off topic:
Your logic is over complicated. It can be greatly simplified to (pseudo code):
countValley(String s) {
currentLevel = 0
valleyCount = 0
for (step in s) {
if step == 'U' {
++currentLevel;
if (currentLevel == 0) { // returning to sea level
++valleyCount
}
} else if step == 'D' {
--currentLevel;
}
}
return valleyCount
}
to compare wrapper Class need to use .equals.
can use Objects.equals :
java.util.Objects.equals(firstInteger, secondInteger);
for case above :
if(java.util.Objects.equals(map.get('D'), map.get('U'))){
sea = true;
}
First, don't use '=='. Use .equals for all classes extends Object.
to compare content of wrapper classes (Integer, Float, Long, Double), use .equals(). "==" would compare the references of both objects. The references might be different even though both contain the same content. You will can however use "==" when you are comparing value types such as int, float, long, double.
Solution 1: If you must use a HashMap, looks like iteration in HashMap is the problem. Below a link to how to do it. As you iterate, build your logic for counting hills and valleys. How to efficiently iterate over each entry in a Java Map?.
Solution 2: Use Array instead of HashMap. After building it, find the D sequences and so on.

why is (Integer) 1 == (Integer) 1 returns true, but (Integer) 200 == (Integer) 200 returns false? [duplicate]

This question already has answers here:
Why is 128==128 false but 127==127 is true when comparing Integer wrappers in Java?
(8 answers)
Closed 7 years ago.
I tried to print the results, but unable to get the reason behind this.Anyhelp would be greatly appreciated.
I guess we're talking about java? (:
Java has a very weird way of storing integers. I can give you the long answer, but it can be easily found around the forums.
Long story short, when integers pass 127, their length becomes too long to store normally, and thus the default comparing operator between them does not work properly. If you need to make this comparison, I'd advise using some other numeric type, but usually just storing them and using the .equals() function would do - It compares objects by value. Example:
//in some package , inside some function
// if((Integer)128==(Integer)128)
// {
// // this will never happen
// }
// if((Integer)128).equals((Integer)128))
{
// this will happen.
}

Java: Unexpected Type Error [duplicate]

This question already has answers here:
Replace a character at a specific index in a string?
(9 answers)
Closed 8 years ago.
Can someone help me understand why I'm getting an "Unexpected Type Error"?
if(s.charAt(i-1) == ' '){
String sub = s.substring(i, s.indexOf(' ')+1);
for(int j = 0; j < sub.length()/2; j++){
char temp;
temp = sub.charAt(j);
sub.charAt(j) = sub.charAt(sub.length()-1-j);
sub.charAt(sub.length()-1-j) = temp;
sub = sub+" ";
complete = complete+sub;
}
}
I'm getting the error on lines 6 and 7. I can't figure out why and I'd appreciate the help!
charAt() returns the character. It is not a left side operand aka you cannot assign a value to it.
Strings are immutable, which means you cannot change them (this seems to be your intention).
Instead: create a new String and add to that.
If this confused you, I try to elaborate a little: the assignment operator takes whatever is on the right and tries to shove it into whatever is on the left of it.
The problem here is that some things do not like it when you try to shove other things into them. You cannot put everything on the left that you want. Well, you can try:
"everything" = 5;
but this does not work, neither does this:
"everything" = 42;
Set aside what that last snippet failing implies to the universe and everything, your problem at hand is that charAt() is also one of those things that do not like it on the left side of the assignment operator.
I'm afraid there's no way to turn charAt() into one of those things that like it on the left side. A week after stranding on a deserted island without any plants but only solar powered refrigerators filled with steaks, this probably works:
vegetarian = meat;
Even though the vegetarian doesn't like it there, he'd accept his situation being on the left side of the = operator. He eats some steaks.
This does not hold true for what you are trying, though. There's no such deserted island for charAt().
In these lines you're trying to set the value of functions' return. This is illegal
sub.charAt(j) = sub.charAt(sub.length()-1-j);
sub.charAt(sub.length()-1-j) = temp;
as far as I see you're trying to change the characters of a String, but Strings are imutable objects. So you'll need to use a StringBuffer to set the values.

Trying to find a true condition for an empty record [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
OK. Im reading all the objects from an arraylist and grabbing thier names.
for(Contractor o : fa.allValues){
System.out.println(o.getName());
}
This returns
Bobs Tools
//The problem
Ic Remodeling
Fred and Nobby
Dogs With Tools
Dogs With Tools
Bitter Homes and Gardens
Etc etc
Now....when i create and add an object, i want to put the new object in any empty spaces that it finds. It should find an empty space when it comes to the 2nd record.
However........
String str = allValues.get(1).getName(); // where 1 is the location of the empty record
all the following returns false
System.out.println(str == "");
System.out.println(str == " ");
System.out.println(str == null);
I want to input a condition that returns true. What basic issue have i over looked here?
use equals for testing equality of string and not ==
Your equality for an empty string is wrong. In java you should compare it using the equals-method.
I would recommend using the apache commons lang StringUtils.isEmpty() method.

Do While Questions [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 9 years ago.
Ok, I'm taking a Comp. Prog. class at my high school and the teacher that "teaches" the class knows practically nothing about programming. I joined the Java UIL team and am teaching the class with curriculum from some college website. Anyways, I started writing a Body Mass Index Calculator yesterday, and have had success but my problem is that I want to have a println prompt to run the program again after the calculations have been completed. Now, I have learned the Do While loop for this occasion, but my problem is with the scanner. I want to receive input as a string but when I do
String a = sc.nextLine();
outside of the do, it says that y or yes, cannot be resolved to a variable. A friend suggested switch cases, what do you think? I use Eclipse BTW.
String a = sc.nextLine();
do{
wow(); //My method name
}while(a == y); //Error is here
To compare objects in java use .equals() method instead of "==" operator
Use while(a.equals("y")); instead of while(a == y);
while(a == y);
This will never work for two reasons:
== compares references, not the contents of the object. So here it is only checking that a and y point to the same object, not that they contain the same thing.
You have not declared y anywhere. I'm assuming that you want to compare a against the literal string "y", in which case you should be using a.equals("y").
Your loop can be structured like this:
String input;
do {
wow();
input = scanner.nextLine();
} while(input.equalsIgnoreCase("y")); //using equalsIgnoreCase because user
//can input "y" or "Y".

Categories

Resources