I have the code which tries to append 2 SttringBuffers:
logBuf.append(errStrBuf);
In logs I see following trace:
java.lang.StringIndexOutOfBoundsException: String index out of range: 90
at java.lang.AbstractStringBuilder.getChars(AbstractStringBuilder.java:325)
at java.lang.StringBuffer.getChars(StringBuffer.java:201)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:404)
at java.lang.StringBuffer.append(StringBuffer.java:253)
I cannot understand the cause of the issue.
Can you provide example with constants?
Can it be related with concurrency?
Can you propose solution?
Yes, it can have to do with concurrency. As per the doc:
This method synchronizes on this (the destination) object but does not
synchronize on the source (sb).
So, if errStrBuf is changed in the process, it may yield this error. Synchronize on it yourself, as such:
synchronize (errStrBuf) {
logBuf.append(errStrBuf);
}
using the same synchronized-block wherever the errStrBuf is changed.
Some poking around the Java sources shows StringBuffer.append(StringBuffer sb) delegates to AbstractStringBuilder.append(StringBuffer sb) which does this:
// Length of additional sb.
int len = sb.length();
// Make sure there's room.
ensureCapacityInternal(count + len);
// Copy them through.
sb.getChars(0, len, value, count);
StringBuffer.getChars delegates to AbstractStringBuilder again so getChars looks a bit like:
public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
{
if (srcBegin < 0)
throw new StringIndexOutOfBoundsException(srcBegin);
if ((srcEnd < 0) || (srcEnd > count))
throw new StringIndexOutOfBoundsException(srcEnd);
if (srcBegin > srcEnd)
throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
}
Note that you are getting String index out of range: 90 so it must be the srcEnd > count returning true. So the string that is being appended is now shorter than the len that was passed. Clearly it must have been fiddled with by another thtread.
Related
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.
The task was to write a method to return the least value of an array.
Would someone quickly look over my code?
public static int findMinimum (int [] array) {
for (int kohlrabi = 0; kohlrabi < array.length; kohlrabi++) {
for (int zwiebel= 0; zwiebel < array.length; zwiebel ++) {
if (array [zwiebel] < array [kohlrabi]) {
kohlrabi = zwiebel -1;
break;
}
int spinat = array [kohlrabi];
if (zwiebel == array.length-1) {
return spinat;
}
}
}
}
Exception in thread "main" java.lang.Error: Unresolved compilation
problem: This method must return a result of type int
at Abgabe7.ArrayExercises.findMinimum(ArrayExercises.java:38)
It's a homework for my school and I definitely understood the logic behind it but cannot find my fault.
Thanks Max
I don't think you need to have two loops. One loop would work.
Simply loop though the array keeping a variable which is the lowest you've found.
You should declare a global variable before the loop then use only one for loop in your code as follows:
int zwiebel= 0;
for (int kohlrabi = 0; kohlrabi < array.length; kohlrabi++) {
if (kohlrabi == 0){
zwiebel = array[kohlrabi];
}
if (array[kohlrabi] < zwiebel) {
zwiebel = array[kohlrabi];
}
}
The lowest value in your array is now stored in the variable zwiebel.
The real mistake is that you are not taking the possibility of an empty array into account. One thing to learn in programming is to think of all possibilities (maybe you’ve discovered that already). An array in Java (and most other languages) can have length 0, that is, have no elements in it. When array.length is 0, your outer for loop doesn’t execute, so we get down to the bottom of the method without having returned anything and without having anything to return.
Java is dumb, but nevertheless smart enough to discover this problem for you. When your method is declared to return an int, it insists that it too can see that it will return an int in all cases. In your method it cannot, which is what the following message is trying to tell you:
This method must return a result of type int
One possible fix — and I may be showing you something that you haven’t learned in school yet — is to insert the following statement in the end of your method:
throw new IllegalArgumentException("Cannot find the minimum of an empty array");
Throwing an exception is an alternative to returning a value, so this statement will make Java happy. If you actually try to find the minimum of an empty array, your program will crash and give you the message “Cannot find the minimum of an empty array”. But finding the minimum of an array that has numbers in it should work now.
That said the others are correct: Your way of finding the minimum is overly complex. I have been staring at your code and still have not understood how it works. Such code is not good. In real life you will be writing code that others will need to read and change after you, and no one can change code they don’t understand, so your code would not be useful. More important than writing code that works correctly is writing readable code.
Edit: There are variations on how to do this in a simple way. For a school exercise using a for loop I would write:
public static int findMinimum (int [] array) {
if (array.length == 0) {
return 42; // or whichever value is desired in this case
}
int niedrichsteSoWeit = array[0];
for (int index = 1; index < array.length; index++) {
if (array[index] < niedrichsteSoWeit) {
niedrichsteSoWeit = array[index];
}
}
return niedrichsteSoWeit;
}
For production code I probably would not write a method but use the built-in functionality, for example:
IntStream.of(myIntArray)
.min()
.ifPresentOrElse(min -> {
// do something with min
}, () -> {
// do whatever you want to do when the array is empty
});
Don’t worry if you don’t understand a bit of this snippet. It’s mostly for more experienced programmers who might happen to read this answer.
basically I have a brute force password guesser(I realize it's not very efficient) I have a process I want to make into a recursive method that i can pass a length integer and it will run with that amount of characters.
here is the code:
public static void generatePassword(int length)
{
// should be a recusive function learn how to do that
// 1 interval
for(int i =32;i<127;i++)// ascii table length
{
System.out.println((char)i);
}
// 2 interval
for(int z =32;z<127;z++)// ascii table length
{
for(int q =32;q<127;q++)// ascii table length
{
System.out.println((char)z+""+(char)q);
}
}
// 3 interval
for(int w =32;w<127;w++)// ascii table length
{
for(int o =32;o<127;o++)// ascii table length
{
for(int g =32;g<127;g++)// ascii table length
{
System.out.println((char)w+""+(char)o+""+(char)g);
}
}
}
}
the intervals return a string with that length example: 3rd interval will return every possible string combination with a length of 3. if anyone can help me automate this process and explain(i would like to learn rather then copy and paste) that would be great ! :)
A recursive method is a method that calls itself, it has a base-condition (also called stop condition) which prevents it from going into an infinite loop.
Lets take the first interval as an example:
for(int i = 32; i < 127; i++) { // ascii table length
System.out.println((char)i);
}
we can create a recursive method that'll do the same thing:
private void interval1(int i) {
if (i < 32 || i >= 127) return;
System.out.println((char)i);
interval1(i + 1);
}
in order to use it for our use-case, we should call this method with i=32: interval(32)
Hope this helps!
The function
Note that this will be EXTREMELY INEFFICIENT. This shouldn't ever be done in practice, since the number of String objects created is MIND-BOGGLINGLY HUGE (see bottom of answer)
public void recursivePrint(String prefix, int levels) {
if (levels <= 1) {
for (int i = 33; i < 127; ++i) {
System.out.println(prefix+(char)i);
}
} else {
for (int i = 33; i < 127; ++i) {
recursivePrint(prefix+(char)i, levels-1);
}
}
}
Then you call it with:
recursivePrint("", 5); // for printing all possible combinations of strings of length 5
The way it works
Each call to a function has it's own memory, and is stored seperately. When you first call the function, there is a String called prefix with a value of "", and an int called 'levels' which has a value of 5. Then, that function calls recursivePrint() with new values, so new memory is allocated, and the first call will wait until this new call has finished.
This new call has a String called prefix with a value of (char)34+"", and a levels with a value of 4. Note that these are completely separate instances of these variables to the first function call because remember: each function call has it's own memory (the first call is waiting for this one to finish). Now this second call makes another call to the recursivePrint() function, making more memory, and waiting until this new call finishes.
When we get to levels == 1, there is a prefix built up from previous calls, and all that remains is to use that prefix and print all the different combinations of that prefix with the last character changing.
Recursive methods are highly inefficient in general, and in this case especially.
Why you should never use it
This method is not just inefficient, though; it's infeasible for anything useful. Let's do a calculation: how many different possibilities are there for a string with 5 characters? Well there's 127-33=94 different characters you want to choose, then that means that you have 94 choices for each character. Then the total number of possibilities is 94^5 = 7.34*10^9 [that's not including the 5+ bytes to store each one] (to put that in perspective 4GB of RAM is around 4*10^9 bytes)
Here is your method implemented using recursion:
public static void generatePassword(int length, String s) {
if (length == 0) {
System.out.println(s);
return;
}
for (int i = 32; i < 127; i++) {
String tmp = s+((char) i);
generatePassword(length - 1, tmp);
}
}
All you have to do is to pass length and initial String (ie "") to it.
At if statement there is checked, if recursion should be stopped (when length of generated password is equals to expected).
At for-loop there is new character added to actual String and the method is invoked with shorter length and a new String as an argument.
Hope it helps.
I've searched extensively online but all solutions I've found use two parameters to keep track of the size of the area being used. This would be easy if I was allowed to do that, but I'm not. As you can see below, the code lacks a stop value, because I have no idea how to retain the original information.
This is the code on Wikipedia, you can see they use imin and imax for tracker variables: http://en.wikipedia.org/wiki/Binary_search_algorithm#Recursive
My (very incorrect) code is below. The mid variable doesn't mean anything, because I don't know how to set low and high correctly if I'm not allowed to have any extra arguments in the function.
public static int findRecursiveB( String s, char c)
{
int low = 0;
int high = s.length()-1;
int mid = (low+high)/2;
if (s.charAt(mid) < c) {
return findRecursiveB(s.substring(low, mid), c);
}
else if (s.charAt(mid) >= c) {
return findRecursiveB(s.substring(mid+1, high), c);
}
else return mid;
}
One crucial point here is what does the original String s contain? For this to work, it has to be a sorted String, meaning that the characters in the String must be in order. Specifically, it looks like you've written code that expects s to be sorted in reverse order. Otherwise, unless I'm totally missing something, your code does exactly what it is supposed to: no need to pass extra params because you are passing in the substring on each recursive call.
Otherwise, good job.
My free webhost appends analytics javascript to all PHP and HTML files. Which is fine, except that I want to send XML to my Android app, and it's invalidating my files.
Since XML is parsed in its entirety (and blows up) before passed along to my SAX ContentHandler, I can't just catch the exception and continue merrily along with a fleshed out object. (Which I tried, and then felt sheepish about.)
Any suggestions on a reasonably efficient strategy?
I'm about to create a class that will take my InputStream, read through it until I find the junk, break, then take what I just wrote to, convert it back into an InputStream and pass it along like nothing happened. But I'm worried that it'll be grossly inefficient, have bugs I shouldn't have to deal with (e.g. breaking on binary values such as embedded images) and hopefully unnecessary.
FWIW, this is part of an Android project, so I'm using the android.util.Xml class (see source code). When I traced the exception, it took me to a native appendChars function that is itself being called from a network of private methods anyway, so subclassing anything seems to be unreasonably useless.
Here's the salient bit from my stacktrace:
E/AndroidRuntime( 678): Caused by: org.apache.harmony.xml.ExpatParser$ParseException: At line 3, column 0: junk after document element
E/AndroidRuntime( 678): at org.apache.harmony.xml.ExpatParser.parseFragment(ExpatParser.java:523)
E/AndroidRuntime( 678): at org.apache.harmony.xml.ExpatParser.parseDocument(ExpatParser.java:482)
E/AndroidRuntime( 678): at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:320)
E/AndroidRuntime( 678): at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:277)
I guess in the end I'm asking for opinions on whether the InputStream -> manually parse to OutputStream -> recreate InputStream -> pass along solution is as horrible as I think it is.
I'm about to create a class that will take my InputStream, read
through it until I find the junk, break, then take what I just wrote
to, convert it back into an InputStream and pass it along like nothing
happened. But I'm worried that it'll be grossly inefficient, have bugs
I shouldn't have to deal with (e.g. breaking on binary values such as
embedded images) and hopefully unnecessary.
you could use a FilterStream for that no need for a buffer
best thing to do is add a delimiter to the end of the XML like --theXML ends HERE -- or a char not found in XML like a group of 16 \u04 chars (you then only need to check every 16th byte) to the end of the XML and read until you find it
implementation assuming \u04 delim
class WebStream extends FilterInputStream {
byte[] buff = new byte[1024];
int offset = 0, length = 0;
public WebStream(InputStream i) {
super(i);
}
#Override
public boolean markSupported() {
return false;
}
#Override
public int read() throws IOException {
if (offset == length)
readNextChunk();
if (length == -1)
return -1;// eof
return buff[offset++];
}
#Override
public int read(byte[] b, int off, int len) throws IOException {
if (offset == length)
readNextChunk();
if (length == -1)
return -1;// eof
int cop = length - offset;
if (len < cop)
cop = len;
System.arraycopy(buff, offset, b, off, cop);
offset += cop;
return cop;
}
private void readNextChunk() throws IOException {
if (offset <= length) {
System.arraycopy(buff, offset, buff, 0, length - offset);
length -= offset;
offset = 0;
}
int read = in.read(buff, length, buff.length - length);
if (read < 0 && length <= 0) {
length = -1;
offset = 0;
return;
}
// note that this is assuming ascii compatible
// anything like utf16 or utf32 will break here
for (int i = length; i < read + length; i += 16) {
if (buff[i] == 0x04) {
while (buff[--i] == 0x04)
;// find beginning of delim block
length = i;
read = 0;
}
}
}
}
note this misses throws, some error checking and needs proper debugging
"I'm about to create a class that will take my InputStream, read through it until I find the junk, break, then take what I just wrote to, convert it back into an InputStream and pass it along like nothing happened. But I'm worried that it'll be grossly inefficient, have bugs I shouldn't have to deal with (e.g. breaking on binary values such as embedded images) and hopefully unnecessary."
That'll work. You can read into a StringBuffer and then use a ByteArrayInputStream or something similar (like StreamReader if that's applicable).
http://developer.android.com/reference/java/io/ByteArrayInputStream.html
The downside is that you're reading in the entire XML file into memory, for large files, it can be inefficient memory-wise.
Alternatively, you can subclass InputStream and do the filtering out via the stream. You'd probably just need to override the 3 read() methods by calling super.read() and flagging when you've gotten to the garbage at the end and return an EOF as needed.
Free webhost have this issue. I'm still yet to find an alternative still in free mode.