Problems comparing two object variables - java

I am doing a lab for college where I have to compare Moneybags. initially I instantiate them and add money etc. etc.I already have MoneyBag mb0, and mb1,but now I have to compare them with this code...it cannot be changed.
mb0.compare(mb1);
The class is MoneyBag. I need to return "Is Less Than","Is equal to", or "is Greater Than."
I currently have:
public int compare(MoneyBag mb1){
}
However, I cannot access mb0. I can access the int value of mb1. I need to compare them, print out the string literals, and obviously return the String. How would I do that? The top code cannot be changed, I have to make the second code work from it.

Regardless of the language, you should be able to access mb0 using something like in the body of your compare function.
return this.value - mb1.value;
Values of 0 represent "equal", values greater than 0 mean "Greater Than" and values less than 0 mean "Less Than";
Good luck

Related

Get a String value from its hashCode [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 10 months ago.
Improve this question
Is there an easy way to get the value of a string using its hashcode? Let me explain:
I have a string variable which has value Hello Guys. It is saved here: String#dye63g. Now, I want to get the string value Hello Guys from String#dye63g.
Based on your comments on this question, your question is REALLY asking:
For an object whose class does not override the default toString() from java.lang.Object itself, can I derive the value again?
The answer is a resounding no. It's NOT A HASH. It's the fully qualified class name, an # symbol, then in hexdigits (so 0-9a-f, not y and g like in your example), the value returned by System.identityHashCode(obj).
This code has no relationship at all with the value of it and isn't the hashCode of that object. It's, usually, its memory address or some modification of that principle.
You can trivially test this:
class Test {
public static void main(String[] args) {
System.out.println(System.identityHashCode("Hey, there!"));
}
}
Run that a few times. The same value might come out (it depends on your system and VM impl), but now run the same code on a different VM, or on a different computer, or reboot and run it again. Different values come out. That should make it rather obvious that you can't.
A second issue is the pigeonhole principle. That hash value is always exactly 32 bits long (why? Well, System.identityHashCode returns an int and those only have 32 bits. Each letter (0-9a-f) represents 4 bytes, hence why that thing after the # is always 8 characters long: each character is 4 bits, 8*4 = 32.
You can test that too. Copy/paste the collected works of Shakespear into a single gigantic string, and now invoke identityHashCode on that - it's still just a short number.
There are 4 billion different numbers that an int can represent and that's it. However, there are more than 4 billion strings imaginable (there are an infinite amount of them, in fact). Hence, there must exist an infinite amount of different strings that all so happen to hash to, say, 1234abcd. Thus, given the hash 1234abcd, it is impossible to say which string produced it - after all, an infinite amount of strings exist that hash to that value. And that's presuming the hashing is 'constant' (same string results in the same hash, e.g. what string's own .hashCode() method does). System.identityHashCode isn't even that and in fact has no relationship at all to the actual value. The number you get depends on, effectively, the memory load of the system when you boot the JVM, more or less.

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.

Equal ArrayLists (Java)

.containsAll will work but .equals is not working.
You are adding the numbers everytime. You should use local variables or local initialization. Else your passcode list gets 5 more numbers everytime you call your function.
Because you said "a security keypad", I have to say ignore what anyone else says that is technically correct, you are doing it wrong. By storing the passcode in a "plain" format, you might as well just leave a sticky note on the keypad with the passcode on it.
What you should be doing is hashing the input and the passcode and comparing the hashed versions. And don't use hashCode(), that function is unreliable for this purpose. (Example of how to hash)
Also, according to the Java Docs, equals is the correct way to check. You are miss-handling your list instances. You should step through the debugger to see everywhere in your code that you do something that alters your global variables.
I think you have a problem where you are comparing your arrays. Have a look at this SO question: equals vs Arrays.equals in Java
if (digitList.size() == 5 && digitList.equals(passcode)) { // are the arrays the same array?
guideArea.setText("Correct Password.");
digitList.clear();
}
what it should be:
if (digitList.size() == 5 && Arrays.equals(digitList, passcode)) { // are the two arrays CONTENT the same
guideArea.setText("Correct Password.");
digitList.clear();
}

what primitive or what type should we use to represent a telephone number in java?

what type could contain a number like 2023209999 in java?
do you think that using a string type to represent a telephone number is a good idea?
Using a string is a very good idea. Remember that the point of OOP is that different types of data have different usage patterns. So let's look at a phone number patterns.
Do we add phone numbers or perform other arithmetic on them?
Do we split it based on length, match against parts of it, replace parts of it?
The answer to the first question is no. So we don't manipulate them like numbers. The answer to the second question is yes, so we manipulate them like strings.
Now, many here are advocating making phones a class by itself. There is merit in this regard, but I'm addressing the more pressing concern of how do you store the phone number, which is something you need to do no matter if a phone is a class or not. A phone class which stored its data as a number would not be a good fit.
I would write a PhoneNumber class, which uses String as an underlying storage, and adds validation / pretty formatting functionality.
I'd say a String at the least, but personally, I'd make a PhoneNumber object. It's the sort of thing that affords itself to extra methods such as:
boolean isValid();
PhoneNumberUtils.getCountry(PhoneNumber number);
PhoneNumberUtils.getState(PhoneNumber number);
...or whatever. One thing I'd be thinking out for is just letting people put in phone numbers and getting the system to learn the rest. I despise entering data that could be determined by the system. This is just my preference.
On a simpler level, just encapsulating the String in an PhoneNumber object gives your brain a handle ... in a week or so when your brain wonders "Where should this phone number method go?", you may find yourself with a quick answer.
I think that a dedicated PhoneNumber class is the way to go about it. Phone number are not just strings. First and foremost, phone numbers obey to rules, such as: they only contain digits, in the US they can contain either 7 or 10 digits. You'd need a constructor to make sure that your phone numbers are correct.
Second, a class will make it easy for you to steamline the differences between various formats. For instance, 555-4834 and 5554834 are different strings but are the same phone number.
Finally, you'd probably want methods such as: getAreaCode() or getLocalNumber() Calling such a method is much more concise and much less error prone than manipulating a String directly:
String phoneNumber pn = ....;
String localNumber = pn.length() == 7 ? pn : pn.substring(4) :
it's rather late, but I may add my 2 cents ....
I am in telecom and have made best experience to store phone numbers in structures (or objects) with character members of variable length, i.e.
struct TelephoneNumber (
InternationalPrefix VARCHAR;
AreaCode VARCHAR;
Subscriber VARCHAR;
Extension VARCHAR;)
I never store access digits (the zero's, double zeros, pluses etc.), they don't belong to to the telephone number per se but are part of what I may call "dialing rules"
struct DialingRule (
International VARCHAR;
National VARCHAR;
Local VARCHAR;)
typical values for DialingRule are "00", "0", NULL for a direct line, and "000", "00", "0" for a PBX requiring a "0 to get the line"
to "display" a number you can freely format the objects, insert hyphens, brackets or whatever you fancy
to create a dialable sequence I determine the type (international, national or local) by comparing the corresponding elements of the FROM and TO number and add the respective string from the dialing rule set as a prefix.
This all may sound like an overkill, but for international applications with strong requirements on data integrity and with strong links to hardware I didn't come up with any better. It removes ambiguities and the need for hardcoding lenghts etc. when you want to manipulate numbers. It's also easy to prefill parts of the structure from country / city lookup tables containing ISO country codes, IATA city codes and their corresponding prefixes.
Good luck
MikeD
In Germany area codes start with a 0 so a integer representation would lose that information.
Still I wouldn't recommend just using a String.
Instead use a Phonenumber class (or interface and implementations). This approach has some advantages.
If at some point you find that a String is insufficient you just have to change the Phonenumber class not every class that uses Phonenumbers.
Additionally it would allow you to seperate area code and number internally.
If you need to record leading 0 or + for international then you should use a String.
If you ain't worried about these you can just use a long. e.g.
long phoneNumber = 2023209999L; // the L is for a long constant.
It would honestly come down to what you plan to do with it. If you just want to store it to reprint it a string or maybe even a long would be fine, assuming we are dealing with US numbers.
If you want to do something more sophisticated making a Class with containing several strings, one for each component.
Basically just not enough info here to make a real decision.
Using a String Type allows you to break apart the phone number without any voodoo or casting.
For instance, if you change the format of how you accept phone numbers, you'll have to do extra work to get the phone number contatenated if it is a long instead of a string.
Another thing to consider: an int would be too small. the maximum value an int can hold is 2,147,483,647. as far as primitives are concerned, long is your best bet.
It depends on what you're doing. Let's say you want to be able to represent international numbers, local numbers, branch exchange numbers, etc. In this case, a String is a bad choice. It doesn't have any meta-information. You probably want a class to represent a phone number.
As far as what you use to represent the phone number in this class, you could use a BigInteger (to allow you to have international numbers), or more simply, you could store each portion of a phone number as a long.

How to present the nullable primitive type int in Java?

I am designing an entity class which has a field named "documentYear", which might have unsigned integer values such as 1999, 2006, etc. Meanwhile, this field might also be "unknown", that is, not sure which year the document is created.
Therefore, a nullable int type as in C# will be well suited. However, Java does not have a nullable feature as C# has.
I have two options but I don't like them both:
Use java.lang.Integer instead of the primitive type int;
Use -1 to present the "unknown" value
Does anyone have better options or ideas?
Update: My entity class will have tens of thousands of instances; therefore the overhead of java.lang.Integer might be too heavy for overall performance of the system.
Using the Integer class here is probably what you want to do. The overhead associated with the object is most likely (though not necessarily) trivial to your applications overall responsiveness and performance.
You're going to have to either ditch the primitive type or use some arbitrary int value as your "invalid year".
A negative value is actually a good choice since there is little chance of having a valid year that would cause an integer overflow and there is no valid negative year.
Tens of thousands of instances of Integer is not a lot. Consider expending a few hundred kilobytes rather than optimise prematurely. It's a small price to pay for correctness.
Beware of using sentinel values like null or 0. This basically amounts to lying, since 0 is not a year, and null is not an integer. A common source of bugs, especially if you at some point are not the only maintainer of the software.
Consider using a type-safe null like Option, sometimes known as Maybe. Popular in languages like Scala and Haskell, this is like a container that has one or zero elements. Your field would have the type Option<Integer>, which advertises the optional nature of your year field to the type system and forces other code to deal with possibly missing years.
Here's a library that includes the Option type.
Here's how you would call your code if you were using it:
partyLikeIts.setDocumentYear(Option.some(1999));
Option<Integer> y = doc.getDocumentYear();
if (y.isSome())
// This doc has a year
else
// This doc has no year
for (Integer year: y) {
// This code only executed if the document has a year.
}
Another option is to have an associated boolean flag that indicates whether or not your year value is valid. This flag being false would mean the year is "unknown." This means you have to check one primitive (boolean) to know if you have a value, and if you do, check another primitive (integer).
Sentinel values often result in fragile code, so it's worth making the effort to avoid the sentinel value unless you are very sure that it will never be a use case.
You can use a regular int, but use a value such as Integer.MAX_VALUE or Integer.MIN_VALUE which are defined constants as your invalid date. It is also more obvious that -1 or a low negative value that it is invalid, it will certainly not look like a 4 digit date that we are used to seeing.
If you have an integer and are concerned that an arbitrary value for null might be confused with a real value, you could use long instead. It is more efficient than using an Integer and Long.MIN_VALUE is no where near any valid int value.
For completeness, another option (definitely not the most efficient), is to use a wrapper class Year.
class Year {
public int year;
public Year(int year) { this.year = year; }
}
Year documentYear = null;
documentYear = new Year(2013);
Or, if it is more semantic, or you want multiple types of nullable ints (Other than Years), you can imitate C# Nullable primitives like so:
class Int {
public int value;
public Int(int value) { this.value = value; }
#Override
public String toString() { return value; }
}
Using the int primitive vs the Integer type is a perfect example of premature optimization.
If you do the math:
int = N(4)
Integer = N(16)
So for 10,000 ints it'll cost 40,000 bytes or 40k. For 10,000 ints it'll cost 160,000 bytes or 160K. If you consider the amount of memory required to process images/photos/video data that's practically negligible.
My suggestion is, quit wasting time prematurely optimizing based on variable types and look for a good data structure that'll make it easy to process all that data. Regardless of that you do, unless you define 10K primitive variables individually, it's going to end up on the heap anyway.
What's wrong with java.lang.Integer? It's a reasonable solution, unless you're storing very large amounts of this value maybe.
If you wanted to use primitives, a -1 value would be a good solution as well. The only other option you have is using a separate boolean flag, like someone already suggested. Choose your poison :)
PS: damn you, I was trying to get away with a little white lie on the objects vs structs. My point was that it uses more memory, similar to the boolean flag method, although syntactically the nullable type is is nicer of course. Also, I wasn't sure someone with a Java background would know what I meant with a struct.
java.lang.Integer is reasonable for this case. And it already implemented Serializable, so you can save just only the year field down to the HDD and load it back.
Another option might be to use a special value internally (-1 or Integer.MIN_VALUE or similar), but expose the integer as two methods:
hasValue() {
return (internalValue != -1);
}
getValue() {
if (internalValue == -1) {
throw new IllegalStateException(
"Check hasValue() before calling getValue().");
}
return internalValue;
}
If you're going to save memory, I would suggest packing several years in a single int. Thus 0 is nil. Then you can make assumptions in order to optimize. If you are working only with the current dates, like years 1970—2014, you can subtract 1969 from all of them and get into 1—55 range. Such values can be coded with only 6 bits. So you can divide your int which is always 32 bit, into 4 zones, with a year in there. This way you can pack 4 years in the range 1970—2226 into a single int. The more narrow your range is, like only 2000—2014 (4 bits), the more years you can pack in a single int.
You could use the #Nullable annotation if using java 7

Categories

Resources