Compare using Collections.sort - java

I am trying to sort a text file which is separated by tabs and trying to sort by the third field, className. I am then going to display it in a table. I wrote the following part, but it is not sorting correctly. Any ideas as to where I am going wrong?
public void sortFile(){
BufferedReader reader = null;
BufferedWriter writer = null;
//Create an ArrayList object to hold the lines of input file
ArrayList<String> lines = new ArrayList<>();
try{
//Creating BufferedReader object to read the input file
reader = new BufferedReader(new FileReader("pupilInfo.txt"));
//Reading all the lines of input file one by one and adding them into ArrayList
String currentLine = reader.readLine();
while (currentLine != null){
lines.add(currentLine);
currentLine = reader.readLine();
}
Collections.sort(lines, (String s1, String s2) -> {
s1 = lines.get(0);
s2 = lines.get(1);
String [] line1 = s1.split("\t");
String [] line2 = s2.split("\t");
String classNameLine1 = line1[2];
String classNameLine2 = line2[2];
System.out.println("classname1=" + classNameLine1);
System.out.println("classname2=" + classNameLine2);
int sComp = classNameLine1.compareTo(classNameLine2);
return sComp;
});
//Creating BufferedWriter object to write into output temp file
writer = new BufferedWriter(new FileWriter("pupilSortTemp.txt"));
//Writing sorted lines into output file
for (String line : lines){
writer.write(line);
writer.newLine();
}
}catch (IOException e){
}
finally{
//Closing the resources
try{
if (reader != null){
reader.close();
}
if(writer != null){
writer.close();
}
}catch (IOException e){
}
}
}

I'ava tried with "comparator".for simplicity my source file is as follows
pippo;pluto;paperino
casa;terra;cortile
primo;secondo;terzo
Comparator<String> comparator = new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
return o1.split(";")[2].compareTo(o2.split(";")[2]);
}
};
lines.sort(comparator);
final output
[casa;terra;cortile, pippo;pluto;paperino, primo;secondo;terzo]
sorted on third field!

Related

Multi word replacement within xml file using java

I have an xml-base .tbx file containing code like this:
<descripGrp>
<descrip type="subjectField">406001</descrip>
</descripGrp>
<langSet xml:lang="en">
<tig>
<term>competence of the Member States</term>
<termNote type="termType">fullForm</termNote>
<descrip type="reliabilityCode">3</descrip>
</tig>
</langSet>
<langSet xml:lang="pl">
<tig>
<term>kompetencje państw członkowskich</term>
<termNote type="termType">fullForm</termNote>
<descrip type="reliabilityCode">3</descrip>
</tig>
</langSet>
</termEntry>
<termEntry id="IATE-290">
<descripGrp>
<descrip type="subjectField">406001</descrip>
</descripGrp>
I want to search and replace within entire (almost 50 MiB) file for codes from the field "subjectField" and replace the with proper text, eg.
406001 is for Political ideology, 406002 for Political institution.
I have a table with codes and corresponding names:
406001 Political ideology
406002 Political institution
406003 Political philosophy
There's five hundred of such codes so doing it by hand would take like forever.
I'm not a programmer (I'm learnig) but I know a little java so I made some little app which, I supposed, would help me, however the result is discouraging (luckily I'm not discouraged :))
That's what I wrote, the result is that it works extremely slow, doesn't replace those codes at all. It processed 1/5 of the file in 15 minutes (!). Additionally there are no new line characters in the output file so the entire xml code is in one line.
Any tips on which way I should go?
File log= new File("D:\\IATE\\export_EN_PL_2017-03-07_All_Langs.tbx"); // TBX file to be processed
File newe = new File("D:\\IATE\\now.txt"); // output file
String search = "D:\\IATE\\org.txt"; // file containing codes "40600" etc
String replace = "D:\\IATE\\rplc.txt"; // file containing names
try {
FileReader fr = new FileReader(log);
String s;
String s1;
String s2;
String totalStr = "";
String tot1 = "";
String tot2 = "";
FileReader fr1 = new FileReader(search);
FileReader fr2 = new FileReader(replace);
try (BufferedReader br = new BufferedReader(fr)) {
try (BufferedReader br1 = new BufferedReader(fr1)) {
try (BufferedReader br2 = new BufferedReader(fr2)) {
while ((s = br.readLine()) != null) {
totalStr += s;
while((s1 = br1.readLine()) != null){
tot1 += s1;
while ((s2 = br2.readLine()) != null){
tot2 += s2;
}
}
totalStr = totalStr.replaceAll(tot1, tot2);
FileWriter fw = new FileWriter(newe);
fw.write(totalStr);
fw.write("\n");
fw.close();
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
Its going to take a lot of redundant work to traverse 2 files to get matching values. Before you replace values in the .tbx files you should set up a properties file to read from. Here's a function that would do that:
public static Properties getProps(String pathToNames, String pathToNumbers){
Properties prop = new Properties();
try{
File names = new File(pathToNames);
BufferedReader theNames = new BufferedReader( new InputStreamReader (new FileInputStream(names)));
File numbers = new File(pathToNumbers);
BufferedReader theNumbers = new BufferedReader( new InputStreamReader (new FileInputStream(numbers)));
String name;
String number;
while(((name = theNames.readLine())!= null)&&((number = theNumbers.readLine())!= null)){
prop.put(number, name);
}
theNames.close();
theNumbers.close();
}catch(Exception e){
e.printStackTrace();
}
return prop;
}
Assuming you are using Java 8, you can check that the function is working with this:
thePropertiesFile.forEach((Object key, Object value) ->{
System.out.println(key+ " " +value);
});
Now you can write a function that will convert properly. Use a PrintStream to achieve the output functionality you want.
static String workingDir = System.getProperty("user.dir");
public static void main(String[] args){
Properties p = getProps(workingDir+"path/to/names.txt",workingDir+"path/to/numbers.txt");
File output = new File(workingDir+"path/to/output.txt");
try {
PrintStream ps = new PrintStream(output);
BufferedReader tbx = new BufferedReader(new InputStreamReader (new FileInputStream(new File(workingDir+"path/to/the.tbx"))));
String currentLine;
String theNum;
String theName;
int c; //temp index
int start;
int end;
while((currentLine = tbx.readLine()) != null){
if(currentLine.contains("subjectField")){
c = currentLine.indexOf("subjectField");
start = currentLine.indexOf(">", c)+1;
end = currentLine.indexOf("<", c);
theNum = currentLine.substring(start, end);
theName = p.getProperty(theNum);
currentLine = currentLine.substring(0,start)+theName+currentLine.substring(end);
}
ps.println(currentLine);
}
ps.close();
tbx.close();
} catch (IOException e) {
e.printStackTrace();
}
}
For numbers that don't exist, this will replace them with a null string. You can update that for your specific use.
If theNum contains multiple values, split into an array:
theName = "";
if(theNum.contains(","){
int[] theNums = theNum.split(",");
for (int num : theNums) {
theName += p.getProperty(num);
theName += ",";
}
theName = theName.replaceAll(",$", ""); //get rid of trailing comma
}
else
theName = p.getProperty(theNum);

How to create item objects from reading a text file?

I'm trying to read data from a text file and create Item Objects with it.
Item Objects have fields String title, String formatt, boolean onLoan, String loanedTo and String dateLoaned. In my save()method, I print every object to a text file in a new line and the fields are seperated by "$" (dollar sign). How can I read the text file line by line and create a new object from each line and add it to an array.
TextFile Example:
StarWars$DVD$false$null$null
Aliens$Bluray$true$John$Monday
public void save() {
String[] array2 = listForSave();
PrintWriter printer = null;
try {
printer = new PrintWriter(file);
for (String o : array2) {
printer.println(o);
}
printer.close();
} catch ( IOException e ) {
e.printStackTrace();
}
}
public void open(){
try{
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
StringBuffer stringBuffer = new StringBuffer();
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuffer.append(line);
stringBuffer.append("\n");
}
fileReader.close();
System.out.println("Contents of file:");
System.out.println(stringBuffer.toString());
}catch ( IOException e ) {
e.printStackTrace();
}
}
Thanks everyone. Here's my final code:
public void open(){
try{
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line;
String[] strings;
while ((line = bufferedReader.readLine()) != null) {
strings = line.split("\\$");
String title = strings[0];
String format = strings[1];
boolean onLoan = Boolean.parseBoolean(strings[2]);
String loanedTo = strings[3];
String dateLoaned = strings[4];
MediaItem superItem = new MediaItem(title,format, onLoan,loanedTo,dateLoaned);
items.add(superItem);
}
fileReader.close();
}catch ( IOException e ) {
e.printStackTrace();
}
}
String line = // input line e.g. "Aliens$Bluray$true$John$Monday"
String[] strings = line.split("\\$"); // use regex matching "$" to split
String title = strings[0];
String formatt = strings[1];
boolean onLoan = Boolean.parseBoolean(strings[2]);
String loanedTo = strings[3];
String dateLoaned = strings[4];
// TODO: create object from those values
Maybe you need to handle null differently (in case you want the String "null" to be converted to null); note that you can't distinguish if null or "null" was saved.
This function converts "null" to null and returns the same string otherwise:
String convert(String s) {
return s.equals("null") ? null : s;
}
Reading the objects to an array
Since you don't know the number of elements before reading all lines, you have to work around that:
Write the number of objects in the file as first line, which would allow you to create the array before reading the first object. (Use Integer.parseInt(String) to convert the first line to int):
public void save() {
String[] array2 = listForSave();
PrintWriter printer = null;
try {
printer = new PrintWriter(file);
printer.println(array2.length);
for (String o : array2) {
printer.println(o);
}
printer.close();
} catch ( IOException e ) {
e.printStackTrace();
}
}
public void open(){
try{
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
StringBuffer stringBuffer = new StringBuffer();
int arraySize = Integer.parseInt(stringBuffer.readLine());
Object[] array = new Object[arraySize];
int index = 0;
String line;
while ((line = bufferedReader.readLine()) != null) {
// split line and create Object (see above)
Object o = // ...
array[index++] = o;
}
//...
}catch ( IOException e ) {
e.printStackTrace();
}
//...
}
or
Use a Collection, e.g. ArrayList to store the objects and use List.toArray(T[]) to get an array.
quick and dirty solution might be...
public void open(){
try{
ArrayList<Item> list = new ArrayList<Item>(); //Array of your ItemObject
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
StringBuffer stringBuffer = new StringBuffer();
String line;
while ((line = bufferedReader.readLine()) != null) {
Item itm = new Item(); //New Item Object
String [] splitLine = line.split("\\$");
item.title = splitLine[0];
item.format = splitLine[1];
item.onLoan = Boolean.parseBoolean(splitLine[2]);
item.loanedTo = splitLine[3];
item.dateLoaned = splitLine[4];
list.add(itm);
stringBuffer.append(line);
stringBuffer.append("\n");
}
fileReader.close();
System.out.println("Contents of file:");
System.out.println(stringBuffer.toString());
}catch ( IOException e ) {
e.printStackTrace();
}
}
But this is won't scale if you need to re-arrange or add new fields.
You could try this to "parse" every line of your file
String[] result = "StarWars$DVD$false$null$null".split("\\$");
for (int i=0; i<result.length; i++) {
String field = result[i]
... put the strings in your object ...
}

Put .txt file data in array

I'm new at java I would like to know how to read a .txt file and then put every single line in an array cell.
.txt file must be formatted as shown:
car //goes in array[0]
boat //goes in array[1]
ship //goes in array[2]
airplane //goes in array[3]
//...and so on..
I've already tried to create a ReadFile class implemented in this way:
import java.io.*;
import java.util.*;
public class ReadFile {
private Scanner x;
public void open(){
try{
x = new Scanner(new File("time_table_data.txt"));
}catch(Exception e){
System.out.println("Could Not Create The File");
}
}
public String read(){
String s = "";
while(x.hasNext()){
String a = x.next();
s = a.format("%s\n",a);
}
return s;
}
public void close(){
x.close();
}
}
The problem is that you don't know how many words there are coming. To solve that, you could use an ArrayList.
List<String> entries = new ArrayList<String>();
while (scanner.hasNext())
{
entries.add(scanner.nextLine());
}
System.out.println(entries);
Access them using the get(int index) method:
String test = entries.get(0); // This will be "car"
if you're willing to use Apache Commons IO then you can do this really easy:
import org.apache.commons.io.FileUtils;
String[] linesArr = new String[0];
List<String> lines = FileUtils.readLines(new File("FILE_NAME.txt"));
if (lines != null) {
linesArr = lines.toArray(linesArr);
}
Just do:
List<String> lines = new ArrayList<String>();
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null) {
lines.add(line); // Add line to list
}
} // Try-with-resources closes reader
You don't need the scanner or anything else fancy when you just looking for whole lines.
If you really need an array not a list at the end you can just read out the array from the final List.
Make a method that reads all data from file and stores in a List as follows.
public ArrayList<String> fileRead(String fileName){
File f;
String s;
FileReader fr = null;
BufferedReader br = null;
ArrayList<String> sl = new ArrayList<String>();
try {
f = new File(fileName);
fr = new FileReader(f);
br = new BufferedReader(fr);
while((s=br.readLine())!=null){
sl.add(s);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(br!=null)
br.close();
if(fr!=null)
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sl;
}

Save content of File as String in Java?

I was working a little bit with config files and file reader classes in java.
I always read/wrote in the files with arrays because I was working with objects.
This looked a little bit like this:
public void loadUserData(ArrayList<User> arraylist) {
try {
List<String> lines = Files.readAllLines(path, Charset.defaultCharset());
for(String line : lines) {
String[] userParams = line.split(";");
String name = userParams[0];
String number= userParams[1];
String mail = userParams[2];
arraylist.add(new User(name, number, mail));
}
} catch (IOException e) {
e.printStackTrace();
}
}
This works fine, but how can I save the content of a file as only one single string?
When I read a file, the string I use should be the exact same as the content of the file (without the use of arrays or line splits).
how can I do that?
Edit:
I try to read a SQL-Statement out of a file to use it with JDBC later on. That's why I need the content of the File as a single String
This method will work
public static void readFromFile() throws Exception{
FileReader fIn = new FileReader("D:\\Test.txt");
BufferedReader br = new BufferedReader(fIn);
String line = null;
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null) {
sb.append(line);
sb.append("\n");
}
String text = sb.toString();
System.out.println(text);
}
I hope this is what you need:
public void loadUserData(ArrayList<User> arraylist) {
StringBuilder sb = new StringBuilder();
try {
List<String> lines = Files.readAllLines(path, Charset.defaultCharset());
for(String line : lines) {
// String[] userParams = line.split(";");
//String name = userParams[0];
//String number= userParams[1];
//String mail = userParams[2];
sb.append(line);
}
String jdbcString = sb.toString();
System.out.println("JDBC statements read from file: " + jdbcString );
} catch (IOException e) {
e.printStackTrace();
}
}
or maybe this:
String content = new Scanner(new File("filename")).useDelimiter("\\Z").next();
System.out.println(content);
Just do that:
final FileChannel fc;
final String theFullStuff;
try (
fc = FileChannel.open(path, StandardOpenOptions.READ);
) {
final ByteBuffer buf = ByteBuffer.allocate(fc.size());
fc.read(buf);
theFullStuff = new String(buf.array(), theCharset);
}
nio for the win! :p
You could always create a Buffered reader e.g.
File anInputFile = new File(/*input path*/);
FileReader aFileReader = new FileReader(anInputFile);
BufferedReader reader = new BufferedReader(aFileReader)
String yourSingleString = "";
String aLine = reader.readLine();
while(aLine != null)
{
singleString += aLine + " ";
aLine = reader.readLine();
}

How can you pick one line from a text file and transform it into an array object?

Okay this is code and I need to somehow take a line from the textfile and transform into an array object. like p[0] = "asdasdasd"
public class Patient2 {
public static void main(String args[])
{
int field = 0;
String repeat = "n";
String repeat1 = "y";
Scanner keyIn = new Scanner(System.in);
// FILE I/O
try{
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream("Patient.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
// Print the content on the console
System.out.println (strLine);
}
//Close the input stream
in.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
ArrayList<Patient1> patients=new ArrayList<Patient1>();
Patient1 p =new Patient1();
//set value to the patient object
patients.add(p);
System.out.println(p);
}
}
Instead of printing it to console you can add it to List<String>
List<String> lines = new ArrayList<String>();
while ((strLine = br.readLine()) != null) {
// Print the content on the console
System.out.println (strLine);
lines.add(strLine)
}
Note: your code can be much cleaner, you can handle closing resources in finally
Just use an ArrayList<String> with add(strline); and use toArray(new String []) to get the array after input stream has been closed.
ArrayList<String> list = new ArrayList<String>();
...
while ((strLine = br.readLine()) != null) {
list.add(strLine);
}
...
String [] s = list.toArray(new String []);

Categories