Groovy Array.addAll method remove the elements from original array - java

Ok I'm sure I'm doing something wrong here.
result = []
for (aMp in arMap) {
println("0 " + result)
println("1 " + aMp)
println("2 " + delegate.findSingleMap(aMp))
result.addAll(delegate.findSingleMap(aMp))
println "3 " + result
}
return result
The println result are the following: (I have 2 element in arMap, so it print the four value 2 times)
0 []
1 [ID:XXX, Type:4]
2 [[First:21/Nov/2013, Type:4, error code:SXR07, ID:XXX, Test ID:5]]
3 [[First:21/Nov/2013, Type:4, error code:SXR07, ID:XXX, Test ID:5]]
0 [[First:21/Nov/2013, Type:4, error code:SXR07, ID:XXX, Test ID:5]]
1 [ID:YYY, Type:4]
2 [[First:12/Oct/2012, Type:4, error code:SXR07, ID:YYY, Test ID:6]]
3 [[First:12/Oct/2012, Type:4, error code:SXR07, ID:YYY, Test ID:6]]
As you can see the findSingleMap function work properly, but the second time I use the AddAll, my result array loose the value XXX.
What am I doing wrong?

As stated by the OP int the comments the method findSingleMap modifies the (global) result variable.
for (aEl in map) {
result = result.findAll { it[aEl.key] == aEl.value }
}
return result
Not writing def in front a variable declares it (in simple scripts) global, which might result in strange behaviour like this. So don't do it, unless you have to codegolf.

Related

Error array index out of bounds in some code

There is an array index out of bounds exception in my recursive function. Can someone try to point out to me why that is the case?
This line: return minChange(a, IntegerList); is having the array index out of bounds exception as well as most likely this line:
return minimumValue(1 + minChange(a - d, integerList), minChange(a, updatedList));
/* Function minChange: Minimum Change
Pseudo-code:
minChange(0, ds) = 0
minChange(a, []) = Failure
minChange(a, d :: ds) = minChange(a,ds) if d > a
minChange(a, d :: ds) = min(1 ++ minChange(a - d, d :: ds) otherwise
*/
public int minChange(int a, List<Integer> integerList) {
//int minimumResult = 0;
int indexNumber = 0;
int d = integerList.get(indexNumber); (line 246)
if(a == 0) {
// If a is 0 return 0
return 0;
} else if(integerList.isEmpty()) {
return -1;
} else if(d > a) {
integerList.remove(indexNumber); // Remove first element from list
// Recursive call to minChange
return minChange(a, integerList); (line 261)
} else {
// Create updatedList and remove first element
List<Integer> updatedList = integerList;
updatedList.remove(indexNumber);
indexNumber++;
return minimumValue(1 + minChange(a - d, integerList), minChange(a, updatedList)); (line 269)
}
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 0 out-of-bounds for length 0
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:246)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:261)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:261)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:261)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:261)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:261)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:261)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:261)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:269)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:269)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:269)
How can I fix this array index out of bounds exception. It seems one line needs to be fixed. If so how can I fix this error? What are some ways?
Why it Fails:
A specific sequence of events that leads to the out of bounds exception would be, for example:
minChange(1, [4]) // goes into second-to-last (else if) case, since 4 > 1. 4 is then removed.
minChange(1, []) // crashes
It's not clear what your code was intended to do in this case, since your pseudo-code doesn't define minChange(a, ds).
Even if we stipulate that the input list has to have more than one item, we'll often hit this same case:
minChange(5,[4, 8])
minChange(1,[8])
minChange(1,[])
I'm not sure what you intended to happen here, but, anyway, there are other issues...
Bugs:
There is very likely a bug in your code with this line:
// this just creates another reference to the existing list
// https://stackoverflow.com/questions/6536094/java-arraylist-copy
// meaning: both recursive calls will operate on the same list
// even though one uses the "updatedList" reference and one uses "integerList"
List<Integer> updatedList = integerList;
Also, the use of indexNumber indicates a bug, since it's only ever used when it has value 0 - the incrementing is pointless. Remember that local variables in the function are getting 'reset' in each recursive call, unless you pass them as a parameter.
Debugging Strategies:
First, clarify what you actually want the algorithm to do.
Then, check what it's actually doing. As a debugging technique, I would recommend adding some print statement at the start of the function call:
System.out.println("minChange(" + a + ", " + integerList + ")");
...so that you can see a log of what happened before the crash. You can also use a debugger for this purpose.
Finally, once it works on some simple cases, write a fuzz tester that checks your algorithm on a bunch of random lists and as of different sizes, to see if there are any cases that you missed.

Java - For Loop stops after one iteration [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
I've been writing a simple JFrame program to solve basic math equations, the program takes 5 values, up to two of which may be null, identifies the correct equation and calculates the null values. This section of code below takes the 5 values in a hashmap, identified by a string (V,U,S,A,T), identifies which ones are null and adds them to a seperate array (nullvalues), which is then iterated through (nullValueLoop) to identify a suitable equation and solve the unknown.
The problem arises in nullValueLoop, it only appears to iterate once, stopping abruptly after the first iteration.
I've added a lot of system.out's while trying to debug this, and have included the console output to hopefully show whats going on. The exception called is from another class (as the program continues) attempting to call the second null value and finding it to be null.
Hopefully i've explained this well, any help is much appreciated.
public void calculate() {
// Stores the keys to reference the null values in HashMap<Double> values;
ArrayList<String> nullvalues = new ArrayList<String>();
for(String tempKey : values.keySet()){
if(values.get(tempKey)==null){
nullvalues.add(tempKey);
System.out.print("Found null value " + tempKey + ", adding to array. \n");
}
}
System.out.print("Beginning loop of nullvalues, of size " + nullvalues.size() + "\n");
nullValueLoop:
for(String nullvalue : nullvalues){
System.out.print("Starting outerloop, iterating nullvalue " + nullvalue + "\n");
EquationLoop:
for(Equation e : registeredEquations){
// Flag to keep ` of if we have any unknowns yet
boolean foundUnknown = false;
// Iterate through the values required
// If the loop does not exit, the equation only requires one of our null values and the program continues.
for(String s : e.getRequiredChars()){
// If we have a null value and havent yet had one, all is good
if(nullvalues.contains(s) && foundUnknown == false){
foundUnknown = true;
// We have more than one null value, abort
} else if(foundUnknown == true && nullvalues.contains(s)){
continue EquationLoop;
}
}
System.out.print("Using equation " + e.getIdentifier() + "\n");
System.out.print("Found suitable equation.\n");
Double returnValue = e.calculate(values, nullvalue);
System.out.print("Calculated return value.\n");
values.put(nullvalue, returnValue);
nullvalues.remove(nullvalue);
System.out.print("Added new value to values array\n");
System.out.print("Calculated value " + nullvalue + " to " + values.get(nullvalue) + "\n");
break EquationLoop;
}
System.out.print("Ending outerloop iteration \n");
}
mainWindow.updateTextBoxes();
}
Console output:
Couldn't load value T | Assigning to null
Couldn't load value A | Assigning to null
Found null value T, adding to array.
Found null value A, adding to array.
Beginning loop of nullvalues, of size 2
Starting outerloop, iterating nullvalue T
Using equation 3
Found suitable equation.
Calculated return value.
Added new value to values array
Calculated value T to 10.0
Ending outerloop iteration
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at uk.co.ElliotPurvis.MainWindow.updateTextBoxes(MainWindow.java:143)
at uk.co.ElliotPurvis.Main.calculate(Main.java:136)
at uk.co.ElliotPurvis.MainWindow.actionPerformed(MainWindow.java:118)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
Process finished with exit code 0
Inside EquationLoop you are modifying the list nullvalues, which is being iterated over by the outer loop. This is undefined behavior, you are not allowed to modify a collection while iteration is in progress.
I'm surprised you didn't get ConcurrentModificationException instead.

preventing Array index out of bounds exception with coins

I am trying to figure out a way to separate a monetary value into quarters, dimes, nickels and pennies in the most efficient way. This is currently my code:
public class CoinReader {
private static int amount = 0;
public static void main(String[] args) {
amount = (int)(Double.parseDouble(args[0])*100);
System.out.println("Five: " + computeCoin(500));
System.out.println("one: " + computeCoin(100) );
System.out.println("Q : " + computeCoin(25) );
System.out.println("D : " + computeCoin(10) );
System.out.println("N : " + computeCoin(5) );
System.out.println("P : " + computeCoin(1) );
}
public static int computeCoin(int cointValue) {
int val = amount / cointValue;
amount -= val * cointValue;
return val;
}
}
I am currently getting an Array index out of bounds exception and I know it has something to do with the String array and the amount variable but I am trying to learn about arrays and I am trying to get this program to work. Any help would be appreciated. Thanks.
You are using args[0] and args appears to be empty.
How do you call your program ? You must have forgotten to pass a parameter.
args array is empty, there is no element with index 0. You have to pass one command line argument to your program. When running from a command line make sure you pass a numeric value as an argument like this:
java CoinReader 113.25
It runs:
javac CoinReader.java
java CoinReader 1230
Ouput
Five: 246
one: 0
Q : 0
D : 0
N : 0
P : 0
Have fun to make it work correctly :-P
EDIT:
As already mentioned by the other guys the parameter String args[] refers to the arguments you provide on the command line when you run your compiled Program. You'll get an ArrayOutOfBondsException when you provide no argument as the array will be empty then.
When I say Have fun to make it work I mean that there seems to be an error in your computeCoin method as it won't output results for P, N, D and Q. But this is beyond your initial question.
SECOND EDIT:
It not just runs. It runs perfectly fine.
java CoinReader 10.11
Output:
Five: 2
one: 0
Q : 0
D : 1
N : 0
P : 1

Algorithm problems, android java

I've a problem but i really don't understand why. The problem is when i want to add an element in my ArrayList.
Here is my code :
ArrayList<Integer> lesCasesCoches = new ArrayList<Integer>();
lesCasesCoches.clear();
Log.w("Test", "je beug pas" + idCasier);
for (int f = 0; f < laCave.requeteIdCasier.size(); f++) {
if (laCave.requeteIdCasier.get(f) == idCasier) {
Log.w("Test", "size" + f);
Log.w("Test", "id casier" + laCave.requeteIdCasier.get(f));
Log.w("Test", "id case" + laCave.requeteIdCase.get(f));
int casesAdd = laCave.requeteIdCase.get(f);
Log.w("Test", "que vaut add" + casesAdd);
lesCasesCoches.add(casesAdd);
Log.w("test", "Cases cochés" + lesCasesCoches.get(f));
}
}
Here is my error log:
test: je beug pas2
test: size2
test: id casier2
test: id case5
test: que vaut add5
==> here the bug message
delvikvm: threadid=1: thread exiting with uncaught exception ( group=0x415072a0)
java.lang.indexOutOfBoundsException: Invalid index 2, size is 1
Sorry for my bad english.
Thank you very much for the time you spend for me
Change
Log.w("test","Cases cochés"+lesCasesCoches.get(f));
to
Log.w("test","Cases cochés"+lesCasesCoches.get(lesCasesCoches.size()-1));
I think this make exception error.
Log.w("test","Cases cochés"+lesCasesCoches.get(f));
change this.
Log.w("test","Cases cochés"+casesAdd);
Few things here:
1) why do you need to clear an Array you just created?
2) you access laCave.requeteIdCase and laCave.requeteIdCasier at the position f but f is only bound to laCave.requeteIdCasier.size(). That probably is crashing because requeteIdCase has lesser elements than requeteIdCasier (whatever those terms mean :) )
It probably happens because of this statement if (laCave.requeteIdCasier.get(f) == idCasier)
because if it's not true then for loop will go forward and increase f hence it won't match with
lesCasesCoches.add(casesAdd);
Log.w("test","Cases cochés"+lesCasesCoches.get(f));
so instead of getting f'th item you should get the last one
Log.w("test","Cases cochés"+lesCasesCoches.get(lesCasesCoches.size()-1));
The error is actually caused by logging:
Log.w("test", "Cases cochés" + lesCasesCoches.get(f));
Explanation:
test: je beug pas2
test: size2
test: id casier2
test: id case5
test: que vaut add5
java.lang.indexOutOfBoundsException: Invalid index 2, size is 1
From the debug log, you add the first Integer 5 from casesAdd into lesCasesCoches when f is 2. Since this is the first time you add the number, the size() of lesCasesCoches is 1. Then, when you call the problematic line, you're trying to access the third (from 0-based index) element of lesCasesCoches, resulting in IndexOutOfBoundsException.
The solution is to either remove the line if it's not really needed, or to use lesCasesCoches.get(lesCasesCoches.size() - 1) to get the last added Integer from lesCasesCoches.

MapReduce returns NaN

I have a M/R function, and I get NaN as a value for some of the results. I dont have any experience with JS. Im escaping JS using Java Drivers.
String map = "function(){" + " emit({"
+ "country: this.info.location.country, "
+ "industry: this.info.industry}, {count : 1}); }";
String reduce = "function(key, values){var count = 0.0;"
+ "values.forEach(function(v){ count += v['count'];});"
+ "return count;}";
MapReduceOutput output = collection.mapReduce(map, reduce, null,
new BasicDBObject("lid", "foo"));
An example ti help clear things:
{"_id":{"country":"gb", "industry":"foo"}, "value":NaN}
Thanks a lot.
I see you have solved the problem, but here's why the problem occurred.
MongoDB may rerun your reduce function on the results of previous reduce passes. This is called a re-reduce.
If a re-reduce occurred in your original scenario, you could end up with values like this:
[
{ count: 1 },
{ count: 1 },
4
{ count: 1 },
{ count: 1 },
{ count: 1 },
3
{ count: 1 },
]
All the { count: 1 } values are emitted by your map function. The numbers 4 and 3 are the results of previous reduce calls. Your reduce function will then access the count property of a number:
count += 4["count"];
A number doesn't have a count property, so it will return undefined. Adding undefined to a number will result in NaN.
To avoid this kind of hard-to-debug problem, you need to make sure your reduce function is idempotent. The easiest way to accomplish this is to return what you emit; the value you return in the reduce function should be of the same format as the values you emit in the map function.
I solved it. Changed the loop, as anirvan said. But still I got a NaN. So i changed the return statement as such:
for(var i in values) { count += values[i].count; } return {count: count}; }
That did the trick. Ill need an extra line to parse it, but IDC.
Considering only the JS part, i'm not sure whether the following part is valid -
values.forEach(function(v){ count += v['count'];});
try this instead -
var v;
for (v in values)
{
....
}
hope that helps!

Categories