Java strange output: [Ljava.lang.String;#1aa8c488 (string.split("\\s")) - java

I have a very simple parser splitting string:
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class Parser {
public static void main(String args[]){
String newLog = new String();
try {
BufferedReader reader = new BufferedReader(new FileReader("/Users/John/IdeaProjects/tomcatParser/src/log.log"));
try {
while ((newLog = reader.readLine()) != null){
System.out.println(newLog.split("\\s"));
//System.out.println(newLog.split(" "));
break;
}
//reader.close();
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
} catch (FileNotFoundException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
}
As you can see, I've got absolutely simple code, but as the result i see :
[Ljava.lang.String;#1aa8c488
What am I doing wrong?

You try to print an array object: this will not print the array members, but the array reference.
One solution: surround with Arrays.asList(), ie:
System.out.println(Arrays.asList(newLog.split("\\s")));
(better solution: use Arrays.toString() as suggested by the other answers. You learn something new every day.)

That's what you get when you try to print an array directly. It uses the toString method of the Object class which prints out the name of the class, the at-sign character and the unsigned hexadecimal representation of the hash code of the object. You get the "identity" of the array rather than a textual representation of its contents.
Instead, use:
System.out.println(Arrays.toString(newLog.split("\\s")));

System.out.println works with string. When you are passing object that is not string its method toString() is called automatically and you see the result of this call.
You are calling System.out.println with array argument and this is how toString() of arrays work. To see better output use
System.out.println(Arrays.toString(newLog.split("\\s")))

Method String.split(String regEx) return array of strings (String[]).
When you try to System.out.println any Object in Java it calls this object toString() method. toString() method for array returns exectly is what you see.
Use System.out.println(Arrays.toString(newLog.split("\\s"))); instead.

instead of :
while ((newLog = reader.readLine()) != null){
System.out.println(newLog.split("\\s"));
//System.out.println(newLog.split(" "));
break;
}
your code should be:
while ((newLog = reader.readLine()) != null){
String [] columns = newLog.split("\\s");
for (String result : columns) {
System.out.print(result);
}
break;
}

Related

Print to file all data types (logger)

I have a class file with a method that takes a string argument and outputs to a file:
public static void logger(String content) {
FileOutputStream fop = null;
File file;
//content = "This is the text content";
try {
file = new File("logs.txt");
fop = new FileOutputStream(file);
// if file doesnt exists, then create it
if (!file.exists()) {
file.createNewFile();
}
// get the content in bytes
byte[] contentInBytes = content.getBytes();
fop.write(contentInBytes);
fop.flush();
fop.close();
System.out.println("Done");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fop != null) {
fop.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
I'm trying to add trace logging to many files using this method and it involves not just String data types, but also doubles etc... I'm not sure how i'd go about including doubles/ints into this method and outputting.
I'm quite new to Java so apologies if this is actually quite a trivial task!
Declare a second method that takes Object as a parameter.
public static void logger(Object content) {
logger(content.toString());
}
This method delegates to your earlier method the logging of the string representation of your object, regardless its type.
Now you can call logger() on strings (ex, logger("The answer"), as well as any other type (ex, logger(42)).
Note that boxing (wrapping a primitive type, such as int, into an object, such as Integer) happens automatically.
If you aim at printing more than one object at a time, you have to provide a method that takes varargs array.
public static void logger(Object... objects) {
String msg = Stream.of(objects).map(Object::toString).collect(Collectors.joining());
System.out.println(msg);
}
Calling logger("The answer is ", 42) will print "The answer is 42".
You can get a String representation of doubles, longs, etc by using their corresponding wrapper class.
Example:
double doubVar = 12.643;
Logger.logger( Double.toString( doubVar ) );
or for integers:
int i = 2;
Logger.logger( Integer.toString( i ) );

Sort the column in a CSV File in Java

I have a CSV file which reads this.
City,Job,Salary
Delhi,Doctors,500
Delhi,Lawyers,400
Delhi,Plumbers,100
London,Doctors,800
London,Lawyers,700
London,Plumbers,300
Tokyo,Doctors,900
Tokyo,Lawyers,800
Tokyo,Plumbers,400
Lawyers,Doctors,300
Lawyers,Lawyers,400
Lawyers,Plumbers,500
Hong Kong,Doctors,1800
Hong Kong,Lawyers,1100
Hong Kong,Plumbers,1000
Moscow,Doctors,300
Moscow,Lawyers,200
Moscow,Plumbers,100
Berlin,Doctors,800
Berlin,Plumbers,900
Paris,Doctors,900
Paris,Lawyers,800
Paris,Plumbers,500
Paris,Dog catchers,400`
Now, I want to sort the column of Salary and write it to a txt file.
I can access the column, but not able to sort it. I am new to this CSV Reading part of Java. Can someone help! How should I store each salary value to a variable.
import java.io.*;
public class Main {
public static void main(String args[]) throws FileNotFoundException
{
String csv="C:\\Users\\Dipayan\\Desktop\\salaries.csv";
BufferedReader br= new BufferedReader(new FileReader(csv));
String line="";
try {
br.readLine();
while((line = br.readLine())!=null)
{
String[] f=line.split(",");
System.out.println(" Salary ="+f[2]);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
You can try something like -
String csv="/home/user/Desktop/salaries.csv";
BufferedReader br= new BufferedReader(new FileReader(csv));
String line;
Map<Integer, String> salaryMap = new TreeMap<Integer, String>();
try {
br.readLine();
while((line = br.readLine()) != null) {
salaryMap.put(Integer.parseInt(line.split(",")[2]), line);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
FileWriter fw = new FileWriter("/home/user/Desktop/salaries.txt");
BufferedWriter bw = new BufferedWriter(fw);
List<String> list = new ArrayList<String>(salaryMap.values());
for (String str : list) {
bw.write(str);
bw.newLine();
}
bw.flush();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
I think you should use map here or may be
List<Integer, String>
In case of map
Map<Integer,String>
where key would be the salary and the string would be the whole complete row.
Let me write some code to help you.
Map<Integer,String> dataMap = new HashMap<Integer,String>();
String row = br.readLine();
String columns[]=row.split(","); // columns[2] has the salary now
dataMap.add(Integer.valueOf(columns[2]),row);
Use bubble sort to saw the content or your customer compare class to sort the map. Check what are the possible sort functions of Collection Api.
You can use even List<Integer,String>
Sort with respect to integer, keep placing the elements on their actual positions and re-generate the file.
EDIT:
You can use tree map since it sorts the data. Just use Treemap of integer as key and string as the value. Put all the values in it and iterate over it, that's all!
Be careful with the map, put will override your previous values.
You can use Arrays.sort that will sort a native array or use guavas Iterables.sortedCopy
Here´s a codebank for Arrays.sort: http://codebunk.com/b/40731608/
Java NIO
Java has provided a second I/O system called NIO (New I/O).
NIO was developed to allow Java programmers to implement high-speed I/O without using the custom native code. NIO moves the time-taking I/O activities like filling, namely and draining buffers, etc back into the operating system, thus allows for a great increase in operational speed.
import java.io.File;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
// ...
Path filePath = new File("csv_file_path").toPath();
Charset charset = Charset.defaultCharset();
List<String> stringList = Files.readAllLines(filePath, charset);
String[] stringArray = stringList.toArray(new String[]{});
Arrays.sort(stringArray, new Comparator<String>(){
public int compare(String first, String second) {
return Integer.valueOf(first.split(",")[2]).compareTo(Integer.valueOf(second.split(",")[2]));
}
});
for (String newstr: stringArray){
System.out.println(newstr);
}
Packages Used in Above Code: -
java.nio.charset :- It encapsulates the character sets and also supports encoders and decoders operation that convert characters to bytes and bytes to characters, respectively.
java.nio.file :- It provides the support for files.
Methods Used: -
toPath() :- (No parameters)
This method returns a java.nio.file.Path object constructed from the this abstract path.
Exception:- InvalidPathException – if a Path object cannot be constructed from the abstract path (see FileSystem.getPath)
Example: -
File file = new File("C:\\sandbox\\test.txt");
System.out.println(file.toPath());
Output:- C:\sandbox\test.txt
Note:- It is mandatory to add an exception for above code
defaultCharset() : - (No parameters)
This method returns the default charset of this Java virtual machine.
public static List <String> readAllLines(Path path, Charset cs) :-
Parameters (path - the path to the file, cs - the charset to use for decoding)
This method read all the lines from the file as a List.
Now, I have converted the List into an Array using toArray() method and implemented a Comparator for sorting an array.
I have overridden the compare method and comparing two strings which are the third string in each sentence after comma(,) and converting them to a number and arranging them in a sorted order.

Number Format Exception while reading from a text file

Here I'm reading text file which contains a integer in each line and I'm printing all the integers which appeared more than once.
As you can see I used Hash Map and I assigned integers as Key and number of occurrence of number as value.
Here I'm getting Number Format Exception here. Can anyone help me with this?
package fileread;
import java.io.*;
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
// TODO code application logic here
HashMap<Integer, Integer> lines = new HashMap<Integer, Integer>();
try {
FileInputStream fstream = new FileInputStream("C:/Users/kiran/Desktop/text.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String str;
while ((str = br.readLine()) != null) {
Integer intObj = Integer.valueOf(str);
if (lines.containsKey(intObj)) {
int x = 0;
x = lines.get(intObj);
if (x == 2) {
System.out.println(intObj);
}
lines.put(intObj, x++);
} else {
lines.put(intObj, 1);
}
}
in.close();
} catch (Exception e) {
System.err.println(e);
}
}
}
It's very likely that your number format exception is happening at this line:
Integer intObj = Integer.valueOf(str);
See the documentation for Integer.valueOf here
I'd guess this is because one of the lines is not an integer
For debugging, I think I'd recommend adding something like this line right at the beginning of your loop:
System.out.println("str = \"" + str + "\"");
The only place I see in that code where you'd be getting a NumberFormatException is from Integer.valueOf. My guess is that you're getting some whitespace or something else into str and when you try to format that as a number, it's failing.
Alternately, if you want to try to catch when it's happening, you could try adding a try/catch around Integer.valueof like this:
Integer intObj = null;
try
{
intObj = Integer.valueOf(str);
}
catch(NumberFormatException nfe)
{
System.err.println("The value \"" + str + "\" is not a number!");
}
Good luck!
Do try to use trim() method before providing str as an argument to the valueOf() method.
str = str.trim();
Integer intObj = Integer.valueOf(str);
And Moreover, since you are using File Input/Output, why not use java.nio package instead of using the old java.io package. That java.nio is better for this kind of work. Do read this for comparison b/w java.nio and java.io
Hope that might help in some way.
Regards

BufferedReader: read multiple lines into a single string

I'm reading numbers from a txt file using BufferedReader for analysis. The way I'm going about this now is- reading a line using .readline, splitting this string into an array of strings using .split
public InputFile () {
fileIn = null;
//stuff here
fileIn = new FileReader((filename + ".txt"));
buffIn = new BufferedReader(fileIn);
return;
//stuff here
}
public String ReadBigStringIn() {
String line = null;
try { line = buffIn.readLine(); }
catch(IOException e){};
return line;
}
public ProcessMain() {
initComponents();
String[] stringArray;
String line;
try {
InputFile stringIn = new InputFile();
line = stringIn.ReadBigStringIn();
stringArray = line.split("[^0-9.+Ee-]+");
// analysis etc.
}
}
This works fine, but what if the txt file has multiple lines of text? Is there a way to output a single long string, or perhaps another way of doing it? Maybe use while(buffIn.readline != null) {}? Not sure how to implement this.
Ideas appreciated,
thanks.
You are right, a loop would be needed here.
The usual idiom (using only plain Java) is something like this:
public String ReadBigStringIn(BufferedReader buffIn) throws IOException {
StringBuilder everything = new StringBuilder();
String line;
while( (line = buffIn.readLine()) != null) {
everything.append(line);
}
return everything.toString();
}
This removes the line breaks - if you want to retain them, don't use the readLine() method, but simply read into a char[] instead (and append this to your StringBuilder).
Please note that this loop will run until the stream ends (and will block if it doesn't end), so if you need a different condition to finish the loop, implement it in there.
I would strongly advice using library here but since Java 8 you can do this also using streams.
try (InputStreamReader in = new InputStreamReader(System.in);
BufferedReader buffer = new BufferedReader(in)) {
final String fileAsText = buffer.lines().collect(Collectors.joining());
System.out.println(fileAsText);
} catch (Exception e) {
e.printStackTrace();
}
You can notice also that it is pretty effective as joining is using StringBuilder internally.
If you just want to read the entirety of a file into a string, I suggest you use Guava's Files class:
String text = Files.toString("filename.txt", Charsets.UTF_8);
Of course, that's assuming you want to maintain the linebreaks. If you want to remove the linebreaks, you could either load it that way and then use String.replace, or you could use Guava again:
List<String> lines = Files.readLines(new File("filename.txt"), Charsets.UTF_8);
String joined = Joiner.on("").join(lines);
Sounds like you want Apache IO FileUtils
String text = FileUtils.readStringFromFile(new File(filename + ".txt"));
String[] stringArray = text.split("[^0-9.+Ee-]+");
If you create a StringBuilder, then you can append every line to it, and return the String using toString() at the end.
You can replace your ReadBigStringIn() with
public String ReadBigStringIn() {
StringBuilder b = new StringBuilder();
try {
String line = buffIn.readLine();
while (line != null) {
b.append(line);
line = buffIn.readLine();
}
}
catch(IOException e){};
return b.toString();
}
You have a file containing doubles. Looks like you have more than one number per line, and may have multiple lines.
Simplest thing to do is read lines in a while loop.
You could return null from your ReadBigStringIn method when last line is reached and terminate your loop there.
But more normal would be to create and use the reader in one method. Perhaps you could change to a method which reads the file and returns an array or list of doubles.
BTW, could you simply split your strings by whitespace?
Reading a whole file into a single String may suit your particular case, but be aware that it could cause a memory explosion if your file was very large. Streaming approach is generally safer for such i/o.
This creates a long string, every line is seprateted from string " " (one space):
public String ReadBigStringIn() {
StringBuffer line = new StringBuffer();
try {
while(buffIn.ready()) {
line.append(" " + buffIn.readLine());
} catch(IOException e){
e.printStackTrace();
}
return line.toString();
}

BufferedReader replacing in loop

I'm trying to make this work, I don't understand why it doesn't work since it makes sense to me, but it doesn't make sense to java it seems.
As you read the code, what I expect is _NAME to be replaced by TEST while maintaining the same structure of the text (keeping \n) to save it later(not done yet)
I also stored it using ArrayList, but the replace never took off either, so I'm clueless
try {
BufferedReader reader = new BufferedReader (new InputStreamReader (
new FileInputStream (temp), "utf-8"));
String line = reader.readLine();
StringBuffer text = new StringBuffer();
while(line != null) {
line.replace("[_NAME]", "TEST");
Logger.info(line);
line = reader.readLine();
}
reader.close();
} catch(FileNotFoundException ex) {
} catch(UnsupportedEncodingException ex) {
} catch(IOException ex ) {}
The correct line is
line = line.replace("_NAME", "TEST");
If you use brackets, you are specifying the characters as individual matches (_, N, A, M and E), and you want to replace the whole match.
Second, the replace method return a new String that contains the modified String. Remember that Strings in Java are immutable, so no method that modifies a String would modify the input object, they will always return a new object.
One possible problem is the fact that you have [] around _NAME but I'm going to go with the "you forgot that replace returns the new string instead of changing it in-situ" option. See here.
In other words, it should changed from:
line.replace ( ...
to:
line = line.replace ( ...

Categories