why System.err.println not output in order? - java

I have a simple java class that uses System.err.println to debug the code as it executes. the purpuse of the class is to find the maximum pairwise product of a given numbers.
following is the code and output.
public class MaxPairwiseProduct {
private static boolean enableLog = true;
static long getMaxPairwiseProductFast(int[] numbers) {
long max_product = 0;
int n = numbers.length;
int firstMaxInt = -1;
int secondMaxInt = -1;
int firstMaxIndex = 0;
int secondMaxIndex = 0;
loge("firstMax initialized :" + firstMaxInt);
loge("secondMax initialized :"+ secondMaxInt);
loge("***********************************************");
for (int firstPassIndex = 1; firstPassIndex < n; firstPassIndex++) {
loge("firstpass : Number " +firstPassIndex);
if (numbers[firstPassIndex] > firstMaxInt )
{
loge("\t firstpass : Found max " +numbers[firstPassIndex]);
firstMaxInt = numbers[firstPassIndex] ;
firstMaxIndex = firstPassIndex ;
}
}
for (int secondPassIndex = 1; secondPassIndex < n; secondPassIndex++) {
loge("secondPassIndex : Number " +numbers[secondPassIndex]);
if (numbers[secondPassIndex] > secondMaxInt && secondPassIndex != firstMaxIndex )
{
loge("\t firstpass : Found max " +secondPassIndex);
secondMaxInt = numbers[secondPassIndex] ;
secondMaxIndex = secondPassIndex;
}
}
max_product = firstMaxInt * secondMaxInt ;
return max_product;
}
public static void main(String[] args) {
FastScanner scanner = new FastScanner(System.in);
int n = scanner.nextInt();
int[] numbers = new int[n];
for (int i = 0; i < n; i++) {
numbers[i] = scanner.nextInt();
}
System.out.println(getMaxPairwiseProductFast(numbers));
}
private static void loge(String s)
{
if (enableLog == true)
{
System.err.println(s);
}
}
private static void log(String s)
{
if (enableLog == true)
{
System.out.println(s);
}
}
static class FastScanner {
BufferedReader br;
StringTokenizer st;
FastScanner(InputStream stream) {
try {
br = new BufferedReader(new
InputStreamReader(stream));
} catch (Exception e) {
e.printStackTrace();
}
}
String next() {
while (st == null || !st.hasMoreTokens()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
}
the output is (from the output window in Netbeans):
It is clear that the output messages is not in the intended order.
It appears to me as if the program execute in multi-thread.
what is the error in my code and why it output like this ?

I found the answer here
Delay in running thread due to system.out.println statement
a stackOverflow member guided me to this.
basically , changing the loge method to the following fixed the issue.
private static void loge(String s)
{
if (enableLog == true)
{
System.err.println(s);
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(MaxPairwiseProduct.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

Related

In the getArray method, the resulting array is always empty

public static void main(String[] args) throws FileNotFoundxception {
File usdCoins = new File("C:\\Users\\saif9\\OneDrive\\Desktop\\USD coins.txt");
getArray(usdCoins);
}
public static void getArray (File coins) {
try {
Scanner reader = new Scanner(coins);
int counter = 0;
while (reader.hasNextDouble()) {
System.out.print(reader.nextDouble() + " / ");
System.out.println(counter);
counter++;
}
double jodCoins[] = new double[counter];
int i = 0;
while (reader.hasNextDouble()) {
jodCoins [i] = reader.nextDouble();
i++;
for (int j= 0; j < i; j++) {
System.out.println(jodCoins[j]);
}
}
}
catch (Exception e) {
// ????
}
You should re-initialise the reader ,after the first while , the reader dont have more double to read , so you need to assign it again to a new Scanner (entries are not clear here if you need to reuse the same data of coins file ) :
public static void main(String[] args) throws FileNotFoundxception {
File usdCoins = new File("C:\\Users\\saif9\\OneDrive\\Desktop\\USD coins.txt");
getArray(usdCoins);
}
public static void getArray (File coins) {
try {
Scanner reader = new Scanner(coins);
int counter = 0;
while (reader.hasNextDouble()) {
System.out.print(reader.nextDouble() + " / ");
System.out.println(counter);
counter++;
}
double jodCoins[] = new double[counter];
int i = 0;
// re-initialise the reader here :
reader = new Scanner(coins);
while (reader.hasNextDouble()) {
jodCoins [i] = reader.nextDouble();
i++;
for (int j= 0; j < i; j++) {
System.out.println(jodCoins[j]);
}
}
}
catch (Exception e) {
// ????
}

The problem with the word display if I have too many blank lines

I did not want to repeat the other question, I solved a problem in which I post the most common word in the text, but I have a problem, it does not work if I have more blank lines, how can I solve it?
I tried other ways of stackoverflow, but failed.
This is my code.
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) {
Map < String, Integer > map = new LinkedHashMap < String, Integer > ();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(System.in));
String currentLine = reader.readLine();
while (currentLine != null) {
String[] input = currentLine.replaceAll("[^a-zA-Z-\"\\n\\n\", \"\\n\"]", " ").toLowerCase().split(" ");
for (int i = 0; i < input.length; i++) {
if (map.containsKey(input[i])) {
int count = map.get(input[i]);
map.put(input[i], count + 1);
} else {
map.put(input[i], 1);
}
}
currentLine = reader.readLine();
}
String mostRepeatedWord = null;
int count = 0;
for (Map.Entry < String, Integer > m: map.entrySet()) {
if (m.getValue() > count) {
mostRepeatedWord = m.getKey();
count = m.getValue();
} else if (m.getValue() == count) {
String key = m.getKey();
if (key.compareTo(mostRepeatedWord) < 0) {
mostRepeatedWord = key;
}
}
}
System.out.println(mostRepeatedWord);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Modify your for loop so that you're not adding to your map on a blank line.
for (int i = 0; i < input.length; i++) {
// Skip the blank lines
if (!input[i].trim().equals("")) {
if (map.containsKey(input[i])) {
int count = map.get(input[i]);
map.put(input[i], count + 1);
} else {
map.put(input[i], 1);
}
}
}

Java - Comparing two huge text files

I am trying to develop a basic java program to compare two huge text files and print non matching records .i.e. similar to minus function in SQL. but I am not getting the expected results because all the records are getting printed even though both files are same. Also suggest me whether this approach is performance efficient for comparing two huge text files.
import java.io.*;
public class CompareTwoFiles {
static int count1 = 0 ;
static int count2 = 0 ;
static String arrayLines1[] = new String[countLines("\\Files_Comparison\\File1.txt")];
static String arrayLines2[] = new String[countLines("\\Files_Comparison\\File2.txt")];
public static void main(String args[]){
findDifference("\\Files_Comparison\\File1.txt","\\Files_Comparison\\File2.txt");
displayRecords();
}
public static int countLines(String File){
int lineCount = 0;
try {
BufferedReader br = new BufferedReader(new FileReader(File));
while ((br.readLine()) != null) {
lineCount++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return lineCount;
}
public static void findDifference(String File1, String File2){
String contents1 = null;
String contents2 = null;
try
{
FileReader file1 = new FileReader(File1);
FileReader file2 = new FileReader(File2);
BufferedReader buf1 = new BufferedReader(file1);
BufferedReader buf2 = new BufferedReader(file2);
while ((contents1 = buf1.readLine()) != null)
{
arrayLines1[count1] = contents1 ;
count1++;
}
while ((contents2 = buf2.readLine()) != null)
{
arrayLines2[count2] = contents2 ;
count2++;
}
}catch (Exception e){
e.printStackTrace();
}
}
public static void displayRecords() {
for (int i = 0 ; i < arrayLines1.length ; i++) {
String a = arrayLines1[i];
for (int j = 0; j < arrayLines2.length; j++){
String b = arrayLines2[j];
boolean result = a.contains(b);
if(result == false){
System.out.println(a);
}
}
}
}
}
Based upon your explanation you do not need embedded loops
consider
public static void displayRecords() {
for (int i = 0 ; i < arrayLines1.length && i < arrayLines2.length; i++)
{
String a = arrayLines1[i];
String b = arrayLines2[i];
if(!a.contains(b){
System.out.println(a);
}
}
For the performance wise, you should try to match the size of the files. If the sizes(in bytes) are exactly the same, you might not need to compare them.

Append strings to a file

I'm creating an application which will get the all the rpms in the table, well when I want to append it to a textfile something wrong, Please see the code below.
public class rpms(){
public static void main(String[] args) {
URLget rpms = new URLget();
try {
getTdSibling(sendGetRequest(URL).toString());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void getTdSibling(String sourceTd) throws FileNotFoundException, UnsupportedEncodingException {
String fragment = sourceTd;
Document doc = Jsoup.parseBodyFragment(fragment);
for (Element table : doc.select("table")) {
for (Element row : table.select("tr")) {
Elements lines = row.select("td");
String linesToStr = lines.text();
String[] linestoStrArray = linesToStr.split("\n");
for (String line : linestoStrArray)
if (!line.contains("Outdated")){
//System.out.println(""+line);// display the rpms that do not have outdated
for (int i = 0; i < lines.size(); i++) {
if(!lines.eq(i).text().toString().equals(" ")){
splitStr(lines.eq(i).text().toString());
}
}
}
}
}
}
public static void splitStr(String str1) throws FileNotFoundException, UnsupportedEncodingException{
ArrayList<String> outputContent = new ArrayList<String>();
String[] split1 = str1.split(" ");
for (int i = 0; i < split1.length; i++) {
if(fileExplode(split1[i])){
System.out.println(split1[i]);
outputContent.add(split1[i]);
}
}
copyFile(outputContent);
}
public static void copyFile(ArrayList<String> fileCon1) throws FileNotFoundException, UnsupportedEncodingException{
PrintWriter writer1 = new PrintWriter("C:\\Users\\usersb\\Downloads\\rpms\\newrpms.txt", "UTF-8");
for(int i = 0 ; i < fileCon1.size() ; i++){
writer1.println(fileCon1.get(i));
}
System.out.println("updated newrpms.txt");
writer1.close();
}
public static boolean fileExplode(String str1) {
boolean hasRPM = false;
String[] split1 = str1.replace(".", " ").split(" ");
for (int i = 0; i < split1.length; i++) {
if ((i + 1) == split1.length) {
if (split1[i].endsWith("rpm")
|| (split1[i].length() > 2 && split1[i].charAt(0) == '.' && split1[i].charAt(1) == 'r'
&& split1[i].charAt(2) == 'p' && split1[i]
.charAt(3) == 'm')) {
hasRPM = true;
}
break;
}
}
return hasRPM;
}
}
After I execute the code. The file is empty. what should I do to get the same output displayed in this statemen System.out.println(split1[i]);
Add writer1.flush(); befor you close the PrintWriter writer1.close();
or
This is a working code for write a String value to text file, Try this in your copyFile method
PrintWriter out = null;
try {
out = new PrintWriter("C:\\45.txt"); //path where you want to create your file
} catch (FileNotFoundException ex) {
}
StringBuffer writesb = null;
writesb = new StringBuffer();
//append text
writesb.append("w");
//Line Spacer.writes to a new line
writesb.append(System.getProperty("line.separator"));
writesb.append("e");
out.print(writesb.toString());
out.flush();
out.close();

Java NumberFormatException Skip Line

I'm writing a program that reads in a list of numbers. Such as:
45
63
74g
34.7
75
I simply want my program to skip lines that contain any letters in them. Any help would be greatly appreciated. Thanks!
If it makes a difference, here is my code:
import java.io.*;
public class ScoreReader {
public static void main(String[] args) {
BufferedReader reader = null;
try {
String currentLine;
reader = new BufferedReader(new FileReader("QuizScores.txt"));
while ((currentLine = reader.readLine()) != null) {
int sum = 0;
String[] nums = currentLine.split("\\s+");
for (int i = 0; i < nums.length; i++) {
int num = Integer.parseInt(nums[i]);
if (num != -1) {
sum += num;
}
}
System.out.println(sum / nums.length);
}
} catch (IOException err) {
err.printStackTrace();
}
catch (NumberFormatException err) {
}
finally {
try {
if (reader != null)
reader.close();
} catch (IOException err) {
err.printStackTrace();
}
}
}
}
When an exception is thrown, execution jumps to the catch block. In what you have, this is after the loop, so the loop doesn't continue, just add a try around parseInt.
try {
String currentLine;
reader = new BufferedReader(new FileReader("QuizScores.txt"));
while ((currentLine = reader.readLine()) != null) {
int sum = 0;
String[] nums = currentLine.split("\\s+");
for (int i = 0; i < nums.length; i++) {
try{
int num = Integer.parseInt(nums[i]);
if (num != -1) {
sum += num;
}
} catch( NumberFormatException nfe )
{
// maybe log it?
}
}
System.out.println(sum / nums.length);
}
} catch (IOException err) {
err.printStackTrace();
}
// catch (NumberFormatException err) {}
finally {
try {
if (reader != null){
reader.close();
} catch (IOException err) {
err.printStackTrace();
}
}
Also note, you are using Integer.parseInt which will throw an exception with the input "34.7", so maybe you wish to use Double.parseDouble
How about using a regex? Like for example:
if (currentLine.matches(".*[a-zA-Z].*")) {
//letters contained.
} else {
//no letters contained.
}
see regex demo: http://regex101.com/r/rQ6oR1
you can try this :
import java.io.*;
public class ScoreReader {
public static void main(String[] args) {
BufferedReader reader = null;
try {
String currentLine;
reader = new BufferedReader(new FileReader("QuizScores.txt"));
while ((currentLine = reader.readLine()) != null) {
int sum = 0;
String[] nums = currentLine.split("\\s+");
for (int i = 0; i < nums.length; i++) {
if (isInt(num)) {
sum += num;
}
}
System.out.println(sum / nums.length);
}
} catch (IOException err) {
err.printStackTrace();
}
finally {
try {
if (reader != null)
reader.close();
} catch (IOException err) {
err.printStackTrace();
}
}
}
public boolean isInt(String num)
{
boolean flag=false;
try
{
int i=Integer.parseInt(num);
flag=true;
}
catch(NumberFormatException e)
{
e.printStackTrace();
}
return flag;
}
}
Based on your comment. if your file contain one number per line . then this would be easiest way.
Scanner sc = new Scanner(new File("QuizScores.txt"));
int sum = 0;
int count =0;
while( sc.hasNext()){
String tmpNum = sc.next();
if (isNumeric(tmpNum)){
sum = sum + (int) Double.parseDouble(tmpNum); // if you want t capture in double use Double instead.
count++;
}
}
System.out.println(sum/count);
public static boolean isNumeric(String str)
{
return str.matches("-?\\d+(\\.\\d+)?"); //match a number with optional '-' and decimal.
}

Categories

Resources