Java Strings not printing above length 4094 - java

So I've got a program that generates large binary sequences, and if the string length goes above 4094 it doesn't print. Here's a code snippet the highlights the problem:
private static void ALStringTest() {
String al = "1";
for (int i = 0; i < 5000; i++) {
al += "1";
System.out.println(al.length());
System.out.println(al);
System.out.println(al.isEmpty());
}
}
What's interesting is the length continues to increase, and the boolean value stays false, but I'm unable to see the strings of length 4095 and above.
It's also not a printing error, as I've attempted to write the strings to xml and they don't appear either, all I get is spaces equal to the strings length.
Edit:
I've tried printing a file using this snippet and I have the same problem:
private static void ALStringTest() throws IOException {
File fout = new File("out.txt");
FileOutputStream fos = new FileOutputStream(fout);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
String al = "1";
for (int i = 0; i < 5000; i++) {
al += "1";
bw.write(al);
bw.newLine();
System.out.println(al.length());
System.out.println(al);
System.out.println(al.isEmpty());
}
bw.close();
}
However, people have confirmed this works on external machines (thanks) (as well as on my own using javac, I'm lead to believe this may be Eclipse specific.
Anyone know why Eclipse might be doing this?

the boolean will stay false as hashcode of al is some value and that of "" is 0, == checks for reference.

So it turns out it was an IDE issue:
Simply copying it to a text editor revealed the strings. I'll update when I find the offending option.

The possible reason of this maybe the defect of console which is rapidly printing output results. So that maybe it's only happening in console output. I've tested those each and the result was sometime it prints false only more than 6 times or sometime it prints only length That shouldn't be happened as scenario. But everything works fine when we use thread and make it sleep even 1 millisecond. The output is fine enough as codes,
class ThreadTest extends Thread {
public ThreadTest() {
super();
}
public void run() {
String al = "1";
for (int i = 0; i < 5000; i++) {
try {
sleep(1);
al += "1";
System.out.println(al.length());
System.out.println(al);
System.out.println(al.equals(""));
} catch (InterruptedException e) {
}
}
}
}
Call this in main method
new ThreadTest().start();

Related

Java variable not being affected

Now this may sound like a question that has been repeated many times before but I've done a day of research with people that has other reasons for this Issue.
I have a function that reads a part of the save file and its been shown that it does receive the correct data. So the error is that the integer variable completely ignores the new variable and shows no change in the live debugger so like many other post it is not just a duplicate object error. I cant seem to pinpoint what is the main issue is here and it's the last major thing holding me back. Any help would be great and I'm very extremely sorry if I did manage to miss a topic about this on the internet.
Code that fails:
#Override
public void read(List<String> data) {
//world positions are not being changed at all
System.out.println(data.get(1));
int test = Integer.valueOf(data.get(1).replaceAll("[^\\d.]", ""));
worldXPos = Integer.valueOf(data.get(0).replaceAll("[^\\d.]", ""));
worldZPos = test;
}
Another class that gives the data:
public void readSaveFunctions(){
if(!gameSaves.exists()){
gameSaves.mkdir();
}
String currentLine;
try {
List<String> data = new ArrayList<String>();
FileReader read = new FileReader(currentFile);
BufferedReader reader = new BufferedReader(read);
String key = "";
while((currentLine = reader.readLine()) != null){
if(currentLine.contains("#")){
key = currentLine;
data = new ArrayList<String>();
}else if(currentLine.contains("*end")){
for(int i = 0; i < saves.length; i++){
String tryKey = "#" + saves[i].IDName();
if(tryKey.equals(key)){
key = "";
saves[i].read(data);
}
}
}else data.add(currentLine);
}
reader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Another way of explaining it is this:
Debugger is set to step - to - step mode so I see each line getting executed at human speed then I get to a line like this but all of the ones setting the variables have the same effect:
worldXPos = Integer.valueOf(data.get(0).replaceAll("[^\\d.]", ""));
and the debugger shows the two integers having different numbers but the instant class variable stays exactly the same with no effect in the debugger after the line goes through.
Update:
I forgot to mention the method has a #override method and it seems that this #override may be causing this issue, now finally I may have a path to follow again
So I found my answer: The AWT thread manage to activate calling a method from another class that changed the integer before it could be read. It really though me off at first because the debugger only showed one of the threads and with no way to know the other one was actively changing it to early. Thanks for all the help :P.

Does a file have to be updated in some way for Java?

So I start with a textfile; this textfile at the start contains a number 3 (amount of woningen) 3 Woningen. I can read them with a Scanner without errors. I can also add a Woning without errors. If a Woning is added, the number on top of the file is incremented with 1.
Problem is as follows:
If a Woning has been added, the file has changed. The number is now 4, and a Woning has been added. However, if I want to read all the Woningen, Java returns an exception on the 4th Woning. So for some reason I can't read the 4th Woning.
What can be the cause of this? Do I have to save the file somehow after changes have been made to the file? Or something else has to be done?
Help is greatly appreciated :)!
EDIT
Note: Woning is the dutch word for House.
Code to read the file:
public static Portefeuille read (String infile) {
try {
Scanner sc = new Scanner (new File(infile));
ArrayList<Woning> wlijst = new ArrayList<Woning>();
Portefeuille p = new Portefeuille();
int woningen = sc.nextInt();
int i = 0;
while (i < woningen) {
sc.nextLine();
String tag = sc.nextLine();
wlijst.add(Woning.read(sc));
wlijst.get(i).setTag(tag);
//System.out.println(wlijst.get(i).getTag());
//System.out.println(wlijst.toString());
p.voegToe(wlijst.get(i));
i++;
}
sc.close();
return p;
}
catch (Exception e) {
System.out.println("Portefeuille: Exception is caught");
Portefeuille p = new Portefeuille();
return p;
}
}
Code to write to the file:
public static void writeToFile (Portefeuille port, int woningen) {
try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("Makelaar.txt", false)))) {
woningen = woningen + 1;
out.println(woningen);
ArrayList<Woning> wlijst = new ArrayList<Woning>();
wlijst = port.woninglijst;
for (int i = 0; i < wlijst.size(); i++) {
if (wlijst.get(i) instanceof KoopWoning) {
KoopWoning kw = (KoopWoning) wlijst.get(i);
KoopWoning.writeToFileK(kw, out);
}
else {
HuurWoning hw = (HuurWoning) wlijst.get(i);
HuurWoning.writeToFileH(hw, out);
}
}
out.close();
}
catch (Exception e) {
System.out.println(e.getMessage());
System.out.println("writeToFile: Exception Caught");
}
}
File looks like this:
3
TE KOOP:
Emmalaan 23
3051JC Rotterdam
7 kamers
koopprijs 300000
energiepeil C
VERKOCHT:
Emmalaan 25
3051JC Rotterdam
5 kamers
vraagprijs 280000
energiepeil A
TE HUUR:
Javastraat 88
4078KB Eindhoven
3 kamers
huurprijs 500
I dont know what woningen is. But as far as I know, after adding the data to file, close the file and then try to read the data in file. This definition is always stuck in my mind that one should close the file after you've the finished your process. I can only guess whether you've done two java class for reading and writing or in a same class of writing and reading methods. Hereafter provide some codes so that all can atleast understand on what you're asking.

Java looping through array - Optimization

I've got some Java code that runs quite the expected way, but it's taking some amount of time -some seconds- even if the job is just looping through an array.
The input file is a Fasta file as shown in the image below. The file I'm using is 2.9Mo, and there are some other Fasta file that can take up to 20Mo.
And in the code im trying to loop through it by bunches of threes, e.g: AGC TTT TCA ... etc The code has no functional sens for now but what I want is to append each Amino Acid to it's equivalent bunch of Bases. Example :
AGC - Ser / CUG Leu / ... etc
So what's wrong with the code ? and Is there any way to do it better ? Any optimization ? Looping through the whole String is taking some time, maybe just seconds, but need to find a better way to do it.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class fasta {
public static void main(String[] args) throws IOException {
File fastaFile;
FileReader fastaReader;
BufferedReader fastaBuffer = null;
StringBuilder fastaString = new StringBuilder();
try {
fastaFile = new File("res/NC_017108.fna");
fastaReader = new FileReader(fastaFile);
fastaBuffer = new BufferedReader(fastaReader);
String fastaDescription = fastaBuffer.readLine();
String line = fastaBuffer.readLine();
while (line != null) {
fastaString.append(line);
line = fastaBuffer.readLine();
}
System.out.println(fastaDescription);
System.out.println();
String currentFastaAcid;
for (int i = 0; i < fastaString.length(); i+=3) {
currentFastaAcid = fastaString.toString().substring(i, i + 3);
System.out.println(currentFastaAcid);
}
} catch (NullPointerException e) {
System.out.println(e.getMessage());
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
fastaBuffer.close();
}
}
}
currentFastaAcid = fastaString.toString().substring(i, i + 3);
Please replace with
currentFastaAcid = fastaString.substring(i, i + 3);
toString method of StringBuilder create new instance of String object every time you call it. It still contain a copy of all your large string. If you call substring directly from StringBuilder it will return a small copy of substring.
Also remove System.out.println if you don't really need it.
The big factor here is you are doing the call to substring over a new String each time.
Instead, use substring directly over the stringbuilder
for (int i = 0; i < fastaString.length(); i+=3){
currentFastaAcid = fastaString.substring(i, i + 3);
System.out.println(currentFastaAcid);
}
Also, instead of print the currentFastaAcid each time, save it into a list and print this list at the end
List<String> acids = new LinkedList<String>();
for (int i = 0; i < fastaString.length(); i+=3){
currentFastaAcid = fastaString.substring(i, i + 3);
acids.add(currentFastaAcid);
}
System.out.println(acids.toString());
Your main problem besides the debug output surely is, that you are creating a new String with your completely read data from the file in each iteration of your loop:
currentFastaAcid = fastaString.toString().substring(i, i + 3);
fastaString.toString() will give the same result in each iteration and therefore is redundant. Get it outside the loop and you will surely save some seconds runtime.
Apart from suggested optimization in the serial code, I will go for parallel processing to reduce time further. If you have really big file, you can divide the work of reading file and processing read-lines, in separate threads. That way, when one thread is busy reading nextline from large file, other thread can process read-lines and print them on console.
If you remove the
System.out.println(currentFastaAcid);
line in the for loop, you will gain quite decent time.

ArrayIndexOutOfBoundsException: 4

I'm writing a little program to analyze some data I have and this code, which worked yesterday, is no longer working.
For the life of me, I can't tell why. To my eye, everything is as it should be. I've tried re-syncing the folder on my computer with my GitHub Repo and still was receiving the same error. Maybe a second pair of eyes could help me out?
The text file being read from can be found here.
Here are the methods referred to by the stack trace:
public static void main(String[] args) throws IOException{
FileManagementMethods fmm = new FileManagementMethods();
fmm.runProgram();
}
void runProgram() throws IOException{
boolean doesFileExist = doesFileExist();
if(doesFileExist){
int numLines = getNumberOfLines();
String[] linesFromFile = getLines(numLines);
WeatherAnalysisMethods wam = new WeatherAnalysisMethods();
wam.parseFileAverageTemp(linesFromFile);
wam.parseFileAverageHumidity(linesFromFile);
wam.predictNextTemperature(linesFromFile);
} else{
try {
throw new IOException("Could not find log.txt in default directory");
} catch (IOException e) {
e.printStackTrace();
}
}
}
void parseFileAverageHumidity(String[] linesFromFile) throws IOException{
int[] humiditiesFromFile = new int[linesFromFile.length];
humiditiesFromFile = getHumiditiesFromFile(linesFromFile.length);
int averageFromFile = 0;
for(int i = 0; i < humiditiesFromFile.length; i++){
averageFromFile += humiditiesFromFile[i];
}
averageFromFile = averageFromFile / humiditiesFromFile.length;
String outString = "Average humidity for whole file = " + averageFromFile;
FileManagementMethods fmm = new FileManagementMethods();
fmm.saveAnalyzedData(outString);
}
int[] getHumiditiesFromFile(int numLines){
int[] humiditiesFromFile = new int[numLines];
FileManagementMethods fmm = new FileManagementMethods();
String[] lines = fmm.getLines(numLines);
int i = 0;
while(1 < numLines){
String[] lineDivides = lines[i].split(",");
String tempString = lineDivides[4];
humiditiesFromFile[i] = Integer.parseInt(tempString);
i++;
}
return humiditiesFromFile;
}
Line 51:
String tempString = lineDivides[4];
And here is the stack trace:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
at org.weatheralert.analysis.WeatherAnalysisMethods.getHumiditiesFromFile(WeatherAnalysisMethods.java:51)
at org.weatheralert.analysis.WeatherAnalysisMethods.parseFileAverageHumidity(WeatherAnalysisMethods.java:22)
at org.weatheralert.analysis.FileManagementMethods.runProgram(FileManagementMethods.java:22)
at org.weatheralert.analysis.Main.main(Main.java:9)
If you guys need more information, don't hesitate to ask.
The problem is here, inside your getHumiditiesFromFile method:
while(1 < numLines){
It should be
while (i < numLines){
Since inside this loop you're calling humiditiesFromFile[i].
As Foo Bar User noted in comment, the error may be here:
String tempString = lineDivides[4];
It would be better to make sure there are at least 4 items in that array.
Besides that, the error noted in the section above (assuming it's not a typo) could also throw this Exception for being in an infinite loop.
You've hardcoded a 4 here without checking to see if it exists:
String tempString = lineDivides[4];
You will need to do some data validation beforehand. You're assuming that the line you read has at least three commas. Either change the code to check, or validate the file.
So, it was a silly issue.... JSoup had a couple bad connections and didn't save some of the data I needed it to save. So it didn't recognize some of the lines of data.
Once I fixed the actual data, it runs without issue again.
I apologize for wasting your time.

Why is my ArrayList not being saved to my file?

Why is ArrayList not being written into "MyCalendar.txt"? Even when I use out.write() it still returns false but does not write to the file.
import java.util.*;
import java.io.*;
public static Boolean addAppointment(ArrayList<String> calendar,
String specifiedDay,
String specifiedTime) {
PrintWriter out = new PrintWriter("myCalendar.txt"); //declare calendar file
for (int i = 0; i<calendar.size(); i++) {
String index = calendar.get(i);
if (index.equals(specifiedDay + "" + specifiedTime))
{
out.println(specifiedDay + "" + specifiedTime);
return false;
}
}
return true;
}
Below 2 are important to flush data to file and close the stream
out.flush();
out.close();
Regards,
you forgot to close it:
out.close()
So, a couple of things here.
If you're using Java 7, you should consider using try-with-resources. This will absolutely ensure that your PrintWriter is closed after you're done.
try (PrintWriter out = new PrintWriter("somefile.txt")) {
// code
} catch (FileNotFoundException e) {
System.out.println("Bang!");
}
Next, there are a few cases in which the file could not be written to, either in part or at all:
calendar.size() == 0
index.equals(specifiedDay + "" + specifiedTime)
If the first condition is met, nothing is written and the method happily returns true. Probably not what you expected.
If the second condition is met, you write the first element, and early return. It would probably be a better idea to place that in your loop condition, and return the return value when you're done looping.
int i = 0;
boolean good = true;
while(good && i < calendar.size()) {
// critical actions
String index = calendar.get(i);
if(index.equals(specifiedDay + "" + specifiedTime)) {
good = false;
}
}
// other code
return good;
If that condition is never met, then nothing is ever written to the file.
The default behavior of PrintWriter is not to automatically flush the buffer. See the PrintWriter Documentation for more details.
Alternatively, you might have a data issue:
String index = calendar.get(i);
if (index.equals(specifiedDay + "" + specifiedTime))
If this condition isn't satisfied, you won't print anything out. Have you made sure this condition is true?

Categories

Resources