When I new a Hashtable, why the put method is invocated? - java

I am reading the code of Hashtable and am confused and have some questions.
I coded like this:
Hashtable table = new Hashtable();
table.put(table, 1);
int code = table.hashCode();
I have two questions:
When I invoke the hashCode method just like the third line code, why isn't it an endless loop? I think it is an endless loop.
When I debug this code, I found that code new Hashtable() will cause the invocation of put method, why?

According to the OpenJDK source I'm reading, there's a guard written specifically to guard against the case where a Hashtable contains itself.
I don't see any reference to put within the constructor. Do you have a trace you could post in your answer?

First off, use a hashmap as it's better in many cases.
Second, this uses Oracle's implementation.
It's not an infinite loop. HashTable.hashCode( simply iterates through the map's elements once. Not infinitely. Unless the table contains itself, where in the source I found it is indeed very hacky but does prevent the recursion. In that case it skips calculating its own hash code returning 0.
Looking at the source, no put( is called. Only the next line calls Put.

Related

Faster when I save the result of a method in a new variable?

I was wondering if it is any helpful helpful for the performance (next to the readability) when I save the result of a method in a new variable for further uses. My thought was, that like this the method only needs to be processed once or is this a misunderstanding and only a waste of memory?
Here I save the result of a method because I will use it multiple times.
byte[] headerAsArray = getHeaderByteArray(currentResponse.getHttpResponse(), currentResponse.getOriginalHost(), currentResponse.getOriginalURI());
bb.writeInt(headerAsArray.length);
bb.writeBytes(headerAsArray);
If you mean you're trying to avoid getHeaderByteArray from being called multiple times, then yes, you're doing exactly the right thing. The "cost" of having one extra local variable is negligible in almost all cases. I'd say it's also more readable than the alternative of:
bb.writeInt(getHeaderByteArray(currentResponse.getHttpResponse(), currentResponse.getOriginalHost(), currentResponse.getOriginalURI()).length);
bb.writeBytes(getHeaderByteArray(currentResponse.getHttpResponse(), currentResponse.getOriginalHost(), currentResponse.getOriginalURI()));
That's awful! It might also be incorrect, if for some reason getHeaderByteArray() can return different results for each call. (Unlikely in this case, but possible in general. There's a big difference between calling System.currentTimeMillis() twice, and calling it once and using the result twice, for example.)
I would probably refactor it further though, by adding a method accepting whatever the type of currentResponse is. Then you can change your code to:
byte[] header = getHeaderBytes(currentResponse);
bb.writeInt(header.length);
bb.writeBytes(header);
If you find yourself writing code like this a lot though, you might also want to write a method which accepts a byte array and writes the length and then the bytes. At that point you could write:
writeDataWithLengthPrefix(getHeaderBytes(currentResponse));
You are right, by saving the result of the method in a variable you avoid calling it multiple times, thus reducing the complexity. The only space that is wasted is the size of the byte array However, you would need the byte array later on so I wouldn't call it a waste. Hope I understood your question.

Iterating with a for loop in Java

I'm trying to figure out what this is actually called and where I can find the answer for it. I can't understand the difference in
for (Treet treet : treets) { }
I don't know what the different "treet" mean. can someone help me or at least tell me what it's called?
for (Treet treet : treets) { }
This is an enhanced for statement (although often referred to as an enhanced for loop). You are saying that you want to do something for every element in some collection of things. (Well, actually, you're doing nothing here, but never mind).
In English: "For every Treet in treets, do something".
Treet is a type. Somewhere you need a class called Treet defined. If it's in a different package, you need to import it.
treets is either an Iterable<? extends Treet>, meaning you could call treets.iterator() and use the result in the standard hasNext()/next() way; or an array of something which extends Treet. It's something you can iterate through.
treet is a single element from the iterable/array. You can use it only inside the body of the loop.
Thats a forach loop, it iterates through the array/list/... and performs the actions defined in the loop to every element in the list which is referenced by treet.

A function providing single object to recursive method

The code is posted for review on review board. My intention is not asking to review the code.
[Maze] : https://codereview.stackexchange.com/questions/33155/maze-code-review
In the above code the function solve does nothing but provide a stack object (reference to object of type stack) which would be used by a code executing recursively.
Since there are so many patterns is there a name for such a function which only assists / or does setup for recursive calls ?
If so any do's / dont's / alternatives ?
I think you did just fine. Every recursive algorithm needs some initial values for it's first step. It's common practice to encapsulate this initial call in another method so the caller doesn't have to bother with those values.
If your initial values would be more complicated to set up, you could encapsulate that in additional methods too. Say your stack needs to have some content instead of being empty. You could do something like this:
public List<Coordinate> solve() {
return getMazePath(0, 0, getInitialStack());
}
This way the solve method stays clear and easy as the entry point of your recursion.

Java Array concept

for(int m=0; m< checkBoxValue.length ; m++)
{
System.out.println("check box in model class"+checkBoxValue[m]+"\n");
}
This loop is to print two values in array. It prints the values But after that it shows array out of bound exception
It seems you're on the wrong track. It's best to set a breaking point on your for loop and debug your code, then go through it step wise. This will reveal where the exception is thrown...
Especially since you say "after that", you might want to review your code after that for loop :-)
Are you sure the Exception is raised here ?
Ohh.. Looks like a mess. The information looks very abstract. You need to be specific, may be you can give more code over here. One possible cause I think of, may be, is Multi-threading.
Only multi-threaded application can do this trick. If so, you better provide synchronization on the origin object of checkBoxValue variable.
Hope that helps....
The code should work fine provided you have done the array initialization correctly.
The posted code should not throw ArrayIndexOutOfBoundsException. Most likely, you are doing something after the loop which accesses an incorrect index of an array.
The only way that the code shown in the question could throw an ArrayIndexOutOfBoundsException is if the toString() method of one of the checkBoxValue[m] objects throws the exception.
Maybe you have overridden the toString() method of the checkBoxValue-class (the array initializer would help identifying this class). Following this theory, the toString() implementation might work fine for the first two elements of the array (they are printed) and may throw an exception for the third element in the array.
This could lead to the error description: This loop is to print two values in array. It prints the values But after that it shows array out of bound exception

Setting Hashmap in a loop

I have the following code:
Map<String, ObjectType> objectMap = new HashMap<String, ObjectType>();
for (ObjectType obj : objects) {
obj.setSomeProperty("property value");
objectMap.put(obj.getADiffProperty(), obj);
}
It seems like during loop iteration some of the obj property changes for different keys than the one currently being set. Is there a problem with the above code? Somehow the reference to obj is being recycled by the for loop?
Also this loop is in an outer loop as well.
Update:
I am providing the full method below. The actual place where I am observing the behavior described above is in the outer map defined as Map<String, Map<String, GlossaryTerm>> loadedTerms = new HashMap<String, Map<String, GlossaryTerm>>(); defined in a Singleton class.
List<Audience> audiences = ContentAccess.getAudienceList();
List<GlossaryTerm> glossaryTerms = ContentAccess.getAllReplacementCIs();
for (Audience audience : audiences) {
Map<String, GlossaryTerm> termMap = new HashMap<String, GlossaryTerm>();
for (GlossaryTerm term : glossaryTerms) {
String definition = term.getProductGlossary().get(audience.getName());
if (definition != null)
term.setDefinition(definition);
termMap.put(term.getPhrase(), term);
}
loadedTerms.put(audience.getChannelId(), termMap);
}
I don't think what you think is happening, is happening. The object reference is what it's supposed to be, for each iteration. I think something else must be happening - that the properties are changing elsewhere, or don't have the values you think they have initially. Put in some printlns to track down what's really going on. The code you've shown can't be changing the wrong properties.
It seems like during loop iteration some of the obj property changes for different keys than the one currently being set. Is there a problem with the above code? Somehow the reference to obj is being recycled by the for loop?
The obj variable will be set to the "next" element of the iterator for objects each time around the loop. If you see the same reference value in obj more than once it can only be because:
the reference value genuinely appears more than once in collection, array or whatever given by objects, or
something in setSomeProperty or getADiffProperty or something else you are doing in the loop is updating objects as a side-effect, or
the objects object has a buggy iterator implementation.
Another possibility is that what you are seeing is different objects with the same adiff values.
To say anything more, I'd need to see more source-code than the simplified snippet you have provided.
EDIT - the extra code you provided has not revealed the problem. (I think we can dismiss any theories involving updating the lists while they are being iterated, or strange side-effects from the setters.)
My suspicion is that one of those lists that the singleton is providing contains duplicates or something else unexpected. It could be that is what is causing your problem.
Do what #Carl suggests and use traceprints and/or a debugger to figure out what is in the Collection singleton and what your code is actually doing.
EDIT 2 - The fact that the collection thingy is a singleton class is probably irrelevant. And the contents of a HashMap DO NOT change randomly or spontaneously. (And there are no little green demons in your code that conspire to make it fail. Trust me on this!)
You seem to have the mindsight of guessing what the problem is and making changes based on those guesses in the hope that they will fix the problem. STOP GUESSING! That is the wrong approach, and will probably only make things worse. What you need to do is debug the code carefully and methodically, gathering hard evidence of what your program is actually doing, and interpreting that evidence carefully ... without resorting to crazy notions that something is changing things randomly.
EDIT 3 - If I was in your situation, I would ask another experienced Java programmer in the team to sit down with me and help me debug the code. I still occasionally need to do this myself, and I've had 10 years+ Java experience and 30+ years programming experience. Sometimes you get a mental block on a problem, and a fresh mind / fresh approach is the answer.
It is not a shameful thing to admit to your team / boss that you are out of your depth and need help.
I'm starting a new answer because - well, it's a new thought here, and the discussion thread was getting rather long.
You haven't (I think) said when the changes happen. But you are (potentially) putting the same term into multiple maps, for different audiences. Nothing to do with the loop variable - just that you are repeatedly using the same list of terms, for each audience. But when you put the term into a map, you also change its definition. But the definition is (potentially) different for each audience. So, concrete example:
Term A has the definition of "x" for audience X, and "y" for audience Y. You have both audiences. Initially, we encounter audience X, so A gets definition "x". A gets added to the map for this audience. Now we iterate to the next audience, and change the definition for A to "y". This changes A everywhere you have a reference to it - including in the map for audience X. This would explain why making a copy eliminates the problem. Is this what you are experiencing?
This might be just a typo error. There is no object declared in your snippet, but your put call uses object.getADiffProperty() rather than obj.getADiffProperty(). Is that intentional?
From where the code is called? May be there are concurrent issues? Are there other threads (is it a webapp?) accessing ContentAccess? And I hope GlossaryTerm is a simple Dto, right?

Categories