how to edit my compare method - java

I want to compare contens of my two txt files and write the different words in other file3.txt file
I want to do compare method in this way to write another txt file. Also I dont
have an error for coding
I don't have a result. here is my code

I just ran your program with the following files and could not reproduce your problem.
deneme1
abc
def
ghi
deneme2
abc
ghi
klm
And deneme3 was created with the following content:
abc
ghi
EDIT
It seems you want the opposite behaviour. Some of your methods are unnecessarily complicated and could be made much shorter by using the right tools of the standard JDK. See below an example of a simplified implementation (that only keeps the words that are not in common between the 2 files) - this example is case sensitive:
public class TextAreaSample {
public static void main(String[] args) throws IOException {
//readAllLines does what you do in readFileAsList
List<String> strings1 = Files.readAllLines(Paths.get("C:/temp/deneme1.txt"), Charset.defaultCharset());
List<String> strings2 = Files.readAllLines(Paths.get("C:\\temp\\deneme2.txt"), Charset.defaultCharset());
Set<String> notInCommon = getNotInCommon(strings1, strings2);
write(notInCommon, "C:\\temp\\deneme3.txt");
}
private static void write(Collection<String> out, String fname) throws IOException {
FileWriter writer = new FileWriter(new File("C:\\temp\\deneme3.txt"));
for (String s : out) {
writer.write(s + "\n");
}
writer.close();
}
private static Set<String> getNotInCommon(List<String> strings1, List<String> strings2) {
//Sets are great to get unique lists and check commonality
Set<String> onlyInFile1 = new HashSet<String>(strings1);
onlyInFile1.removeAll(strings2); //remove strings in s1 AND s2
Set<String> onlyInFile2 = new HashSet<String>(strings2);
onlyInFile2.removeAll(strings1); //remove strings in s1 AND s2
Set<String> notInCommon = new HashSet<>();
notInCommon.addAll(onlyInFile1);
notInCommon.addAll(onlyInFile2);
return notInCommon;
}
}

I have simplified and corrected your code into this:
public class TextAreaSample
{
public static void main(String [] args) throws IOException {
compare(readFileAsList("deneme1.txt"),
readFileAsList("deneme2.txt"));
}
private static void compare(List<String> strings1, List<String> strings2)
throws IOException
{
final Collator c = Collator.getInstance();
c.setStrength(Collator.PRIMARY);
final SortedSet<String>
union = new TreeSet<String>(c),
intersection = new TreeSet<String>(c);
union.addAll(strings1);
union.addAll(strings2);
intersection.addAll(strings1);
intersection.retainAll(strings2);
union.removeAll(intersection);
write(union, "deneme3.txt");
}
private static void write(Collection<String> out, String fname) throws IOException {
FileWriter writer = new FileWriter(new File(fname));
try { for (String s : out) writer.write(s + "\n"); }
finally { writer.close(); }
}
private static List<String> readFileAsList(String name) throws IOException {
final List<String> ret = new ArrayList<String>();
final BufferedReader br = new BufferedReader(new FileReader(name));
try {
String strLine;
while ((strLine = br.readLine()) != null) ret.add(strLine);
return ret;
} finally { br.close(); }
}
}
I have deneme1.txt:
plane
horoscope
microscope
deneme2.txt:
phone
mobile
plane
Output in deneme3.txt:
horoscope
microscope
mobile
phone

My suggestion is don't try to solve everything in one shot.
You can simplify your compare method by using one liner
strings1.retainAll(strings2)
See this for more info
http://docs.oracle.com/javase/6/docs/api/java/util/Collection.html#retainAll(java.util.Collection)
And print the contents of the strings1 and see if it is okay then solve that file writing part.

You are opening the third file deneme3.txt twice without closing it in between. I guess the second time (in write()) an exception will be thrown, so there will be no write. Remove the first occurence of FileWriter writer = new FileWriter(new File("D:\\Denemeler\\deneme3.txt")); (the one in compare()) and you should be fine.

I think you have to flush() your writer before closing it.
private static void write(ArrayList<String> out, String fname) throws IOException {
FileWriter writer = new FileWriter(new File("D:\\Denemeler\\deneme3.txt"));
for (int i = 0; i < out.size(); i++) {
writer.write(out.get(i) + "\n");
}
// Flush the writer before closing it.
writer.flush();
writer.close();
}

Related

how to coverage write file func in java

I made a simple function? to which I give a list of objects and then get their headers (just some strings), then sort and write to a file
when i made a test for this func, coverage was 0 lines and i dont know why
public static void writeToFile(List<Appliances> appliances) throws IOException {
try (FileWriter writer = new FileWriter("\\result.csv")) {
appliances.stream().sorted(Comparator.comparing(Appliances::getName)).collect(Collectors.toList());
String previousClassName = "";
for (var app : appliances) {
if (!app.getClass().getSimpleName().equals(previousClassName)) {
writer.write(app.getHeaders());
writer.write("\r\n");
writer.write(app.toCSV());
writer.write("\r\n");
previousClassName = app.getClass().getSimpleName();
}
}
}
}
so here is my unit test code, also I'm not native english speaker, dont write clever words pls, just a code and a little text would be a perfect solution, thanks a lot
#Test
void writeToFile() throws Exception {
try (FileReader expected = new FileReader(String.valueOf(path));
BufferedReader expectedBR = new BufferedReader(expected);
FileReader result = new FileReader(String.valueOf(path2));
BufferedReader resultBR = new BufferedReader(result);
) {
String line1;
String line2;
while ((line1 = expectedBR.readLine()) != null & (line2 = resultBR.readLine()) != null) {
Assertions.assertEquals(line1, line2);
}
}
}

Comparing two text files in random order with Java

I am trying to compare two text files that are randomized and print out the lines that match in both of the files.
File 1:
Student1
Student2
Student3
Student4
File 2:
Student6
Student1
Student2
I want the output as
Student1
Student2
My code is below.
public static void main(String[] args) throws IOException {
String first = "file1.txt";
String second = "file2.txt";
BufferedReader fBr = new BufferedReader(new FileReader(first));
BufferedReader sBr = new BufferedReader(new FileReader(second));
PrintWriter writer = new PrintWriter("test.txt", "UTF-8");
while ((first = fBr.readLine()) != null) {
String partOne1 = fBr.readLine();
String partTwo1 = sBr.readLine();
while ((second = sBr.readLine()) != null) {
System.out.println(first);
writer.println(first);
break;
}
}
writer.close();
fBr.close();
sBr.close();
It's quite simple=) Try to store all results from first file and compare with all lines from second. It will be like this:
package com.company;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) throws IOException {
String first = "file1.txt";
String second = "file2.txt";
BufferedReader fBr = new BufferedReader(new FileReader(first));
BufferedReader sBr = new BufferedReader(new FileReader(second));
ArrayList<String> strings = new ArrayList<String>();
while ((first = fBr.readLine()) != null) {
strings.add(first);
}
fBr.close();
while ((second = sBr.readLine()) != null) {
if (strings.contains(second)) {
System.out.println(second);
}
}
sBr.close();
}
}
It's better to use memory when possible, your 'while' inside different while can work too long time and obfuskate logic.
Another alternative is to put both your files in two arraylists and use the arraylist's retainAll() method to get the common files. And do the operations on it like printing or something else.
public static void main(String[] args) throws IOException {
String first = "file1.txt";
String second = "file2.txt";
BufferedReader fBr = new BufferedReader(new FileReader(first));
BufferedReader sBr = new BufferedReader(new FileReader(second));
List<String> firstFile = new ArrayList<>();
List<String> secondFile = new ArrayList<>();
PrintWriter writer = new PrintWriter("test.txt", "UTF-8");
while ((first = fBr.readLine()) != null) {
firstFile.add(first);
}
while ((second = sBr.readLine()) != null) {
secondFile.add(second);
}
List<String> commonFile = new ArrayList<>(firstFile);
commonFile.retainAll(secondFile);
System.out.println(commonFile);
writer.close();
fBr.close();
sBr.close();
}
If you are using Java8 , the following is a terse way of achieving this logic. Please note that this is applicable for Java8 only. It uses some lambda expressions and features available without a lot of boilerplate code. Hope you find it amusing atleast
List<String> file1Lines = Files.readAllLines(Paths.get("C:\\DevelopmentTools\\student-file1.txt"), Charset.defaultCharset());
List<String> file2Lines = Files.readAllLines(Paths.get("C:\\DevelopmentTools\\student-file2.txt"), Charset.defaultCharset());
List<String> matchingStrings = file1Lines.stream().
filter(studentInfo -> file2Lines.contains(studentInfo))
.collect(Collectors.toList());
matchingStrings.forEach(System.out::println);
Prints :
Student1 , Student2
If you want an elegant solution:
Sort both
Compare as sorted lists
First of all, this is very simple. Secondly, sorting is so incredibly well optimized, this will usually be faster than anything manually written, and yield elegant and easy to understand code.
Most of the other solutions here are O(n*m). This approach is O(n log n + m log m) with small constants. You could use a hashmap for lookups, which would theoretically yield O(n + m) but may have too large constants.
Here is sample code it will print matching values and also non matching values in 2 lists
private static void getMatchAndDiff(List<String> list1, List<String> list2) {
List<String> tempList2=new ArrayList<>(list2);
List<String> tempList1=new ArrayList<>(list1);
list1.retainAll(list2);
System.out.println("Matching results: ");
list1.forEach(System.out::println);
System.out.println("Non Matching results: ");
tempList2.removeAll(list1);
tempList1.removeAll(list2);
System.out.println(tempList1+"\n"+tempList2);
}

How do I load a file with a bunch of descriptions for objects into an array?

I am currently trying to code my own Magic Item Generator for personal use. Right now I am stuck on trying to load a bunch of spell and object descriptions into arrays that will be called from an array if the spell/object is rolled into the magic items creation.
I am currently stuck trying to load multiple descriptions into an array. I can only seem to put one description into the array before it just quits.
Currently I have this code:
public class LoadDescription {
public static ArrayList<String> descriptions = new ArrayList<String>();
public static void main(String[] args) throws IOException {
File filename = new File("spellconcept.txt");
loadDescriptions(filename);
System.out.println(descriptions.get(0));
// System.out.println(descriptions.get(1));
}
public static void loadDescriptions(File name) throws IOException {
FileReader fr = new FileReader(name);
BufferedReader br = new BufferedReader(fr);
StringBuilder sb = new StringBuilder();
int i = 0;
while (!br.readLine().equals("###")) {
try {
String line = br.readLine();
while (!line.isEmpty()) {
sb.append(" " + line);
line = br.readLine();
}
} catch (IOException e) {
}
;
descriptions.add(sb.toString());
}
i++;
}}
This is the text file I am trying to use. Please ignore the lack of intelligence in it, it's just a test file:
#This is a description of a spell.
I often wonder how often I can write
the word often.Without seeming that it is too often that I write this out.
Does it not seem weird. The quick brown fox jumps over the small red fence.
#This is another description of a spell
#Maybe add another line here, \n see if this works? maybe?
###
here is the modified code:
sample file:
#This is a description of a spell.
I often wonder how often I can write the word often.Without seeming that it is too often that I write this out.
Does it not seem weird. The quick brown fox jumps over the small red fence.
#This is another description of a spell
Apple is fruit.
It is red in colour.
#3rd description
I have a pet.
Its a dog named john.
###
public static ArrayList<String> descriptions = new ArrayList<String>();
public static void main(String[] args) throws IOException {
File filename = new File("C:\\temp\\test.txt");
loadDescriptions(filename);
System.out.println("*************");
for(String ln:descriptions){
System.out.println(ln);
}
}
public static void loadDescriptions(File name) throws IOException {
FileReader fr = new FileReader(name);
BufferedReader br = new BufferedReader(fr);
StringBuilder sb = new StringBuilder();
int i = 0;
String line=null;
while ((line = br.readLine()) != null ) {
if(line.startsWith("#")){
if(i>0){
descriptions.add(sb.toString());
sb = new StringBuilder();
}
}else{
if(!line.isEmpty()){
System.out.println(line);
sb.append(" " + line);
}
}
i++;
}
}
At the top of your loop,
while (!br.readLine().equals("###")) {
you call readLine(), consuming the 1-liner lines, but you don't capture the line itself to process it.

Counting values in a column of a .csv file Java

I'm tasked, by my professor, to write a program to read a .csv file (778 rows (including header row), 8 columns).
I need to:
1. Write a method to receive the name of the file as its argument and then print the number of lines in the file.
public void printNumberOfLinesInFile(String fileName)
Write a method to receive the name of the file as its argument and then print the number of private and non-private colleges.
public void printNumberOfPrivateNonPrivateCollegesInFile(String fileName)
Write a method to receive the name of the file as its argument and then print the private college name with largest out of state tuition.
public void printMostExpensivePrivateCollegeInFile(String fileName)
Write a method to receive the name of the file as its argument and then print the non-private college with largest out of state tuition.
public void printMostExpensiveNonPrivateCollegeInFile(String fileName)
Write a method to receive the name of the file as its argument and then print the number of applications and the number of applicants that are accepted for private and non-private colleges.
public void printNumberOfApplications(String fileName)
Write a method to receive the name of the file as its argument and then print following information for private and non-private colleges.
Average of expenses for books.
Average of expenses for room.
Average of personal expenses.
public void printAverageOfExpenses(String fileName)
Disclaimer: I do not want anyone to do my homework for me. I need to learn so I can apply my knowledge when I graduate and enter industry. I'm simply asking for a hint or a better way at writing the code.
My code thus far:
public class Week14
{
public String data;
public void printNumberOfLinesInFile(String inFile) throws IOException
{
int collegeCount = 0;
FileReader fileRead = new FileReader(inFile);
BufferedReader bufferRead = new BufferedReader(fileRead);
while(true)
{
String line = bufferRead.readLine();
if(line == null)
{
break;
}
collegeCount++;
//System.out.println(line);
}
System.out.println(collegeCount-1 + " Colleges total.");
}
public void printNumberOfPrivateNonPrivateCollegesInFile(String inFile) throws IOException
{
int privateCount = 0;
int nonprivateCount = 0;
int count = 0;
FileReader fileRead = new FileReader(inFile);
BufferedReader bufferRead = new BufferedReader(fileRead);
while((data = bufferRead.readLine())!= null)
{
String line = bufferRead.readLine();
String [] lineItems = line.split(",");
for(int i = 0; i < line.length(); i++)
{
if(lineItems[i].equals("Yes"))
{
privateCount++;
}
}
break;
}
System.out.println(privateCount+" private Colleges.");
System.out.println(nonprivateCount+ " non-private Colleges.");
}
public void printMostExpensivePrivateCollegeInFile(String inFile) throws FileNotFoundException, IOException
{
int mostExpensive = 0;
int currentExpensive = 0;
FileReader fileRead = new FileReader(inFile);
BufferedReader bufferRead = new BufferedReader(fileRead);
while((data = bufferRead.readLine())!= null)
{
String line = bufferRead.readLine();
if(line.equals("OutstateTuition"))
{
System.out.println(line);
}
else
{
System.out.println(line);
}
}
}
public void printMostExpensiveNonPrivateCollegeInFile(String fileName)
{
}
public void printNumberOfApplications(String fileName)
{
}
public void printAverageOfExpenses(String fileName)
{
}
public static void main(String[] args) throws FileNotFoundException, IOException
{
File inFile = new File("College.csv");
FileReader fileReader = new FileReader(inFile);
BufferedReader buffReader = new BufferedReader(fileReader);
Week14 w1 = new Week14();
//w1.printNumberOfLinesInFile("College.csv");
w1.printNumberOfPrivateNonPrivateCollegesInFile("College.csv");
//^^^The above line goes into an infinite loop^^^
//w1.printMostExpensivePrivateCollegeInFile("College.csv");
}
}
The problem is, I'm stuck on trying to count the amount of private and nonprivate colleges. In my method, printNumberOfPrivateNonPrivateCollegesInFile (line 39), I'm running into an exception: java.lang.ArrayIndexOutOfBoundsException: 8
I've asked my professor how I can avoid this, I've looked online and the problem seems to lie with the iterator int 'i'. I'm trying to traverse the array, and 'i' is out of bounds. When I put a '1' in
if(lineItems[i].equals("Yes"))
for my privateCount, there is an output of 67 from privateCount, (I think it is counting the individual characters for some reason).
My question, what would be the most effective way to traverse the entire .csv file, and to access individual columns so I can count them and output them?
Any help would be greatly appreciated.
edit:
I have changed the while loop:
while(true)
{
String line = bufferRead.readLine();
String [] lineItems = line.split(",");
if(line == null)
{
break;
}
for (String lineItem : lineItems) {
privateCount++;
}
}
Now I can traverse the entire .csv file, but I'm receiving a java.lang.NullPointerException when I try and count.
edit 2:
I've redone my while loop again,
while(true)
{
String line = bufferRead.readLine();
String [] lineItems = line.split(",");
for (String lineItem : lineItems) {
if (lineItem.equals("Yes")) {
privateCount++;
}
}
System.out.println(privateCount);
}
I'm now counting the right value for privateCount, but there's a NullPointerException at :
String [] lineItems = line.split(",");
and the loop will not let me put my 'echo' outside of the while-loop without a 'break' statement.
With respect to actual industry-level code, and assuming that assignment did not specifically focus on actual CSV decoding, I would recommend finding and using a library to handle low-level decoding, such as OpenCSV, SuperCSV or CSV-module for Jackson.
This way your code can focus on more interesting part of finding specific values, and not on intricate details like possible escaping and/or quoting of contents.
If the focus is on CSV edge cases this is not the approach to use; but for real production code one hopefully rarely if ever writes the actual low-level decoding part, given the existence of multiple good libraries for the task.
if(lineItems != null && lineItems.length>0){
// do your loop
}
if (lineItem!= null && !lineItem.trim().equals("") && lineItem.equals("Yes")) {
privateCount++;
}
most likely will prevent your null issue
public void printNumberOfPrivateNonPrivateCollegesInFile(String inFile) throws IOException
{
int privateCount = 0;
int nonprivateCount = 0;
FileReader fileRead = new FileReader(inFile);
BufferedReader bufferRead = new BufferedReader(fileRead);
try
{
while(true)
{
String line = bufferRead.readLine();
String [] lineItems = line.split(",");
//System.out.println(Arrays.toString(lineItems));
for (String lineItem : lineItems)
{
if (lineItem!= null && !lineItem.trim().isEmpty() && lineItem.equals("No"))
{
nonprivateCount++;
}
if (lineItem!= null && !lineItem.trim().isEmpty() && lineItem.equals("Yes"))
{
privateCount++;
}
}
//System.out.println(privateCount);
}
}
catch(NullPointerException npe)
{
}
System.out.println(privateCount);
System.out.println(nonprivateCount);
}
Fixed it. I'm now just catching the exception so it isn't as annoying. Thanks all for the help.

text File Dictionary Java

Im coding a dictionary in java that the user inputs the words and they are stored in a .txt file in alphabetical order. When I use the SortWords method on its own it works fine, but when I combine it with the Option1Method which adds words to the dictionary it dosent work. Its like it changes the file type of the text file or something?? Any help would be greatly appreciated
public static void Option1Method() throws IOException {
FileWriter aFileWriter = new FileWriter("wordlist.txt", true);
PrintWriter out = new PrintWriter(aFileWriter);
String word = JOptionPane.showInputDialog(null, "Enter a word");
out.println(word);
out.close();
aFileWriter.close();
String inputFile = "wordlist.txt";
String outputFile = "wordlist.txt";
FileReader fileReader = new FileReader(inputFile);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String inputLine;
List<String> lineList = new ArrayList<String>();
while ((inputLine = bufferedReader.readLine()) != null) {
lineList.add(inputLine);
}
fileReader.close();
Collections.sort(lineList);
FileWriter fileWriter = new FileWriter(outputFile);
PrintWriter out1 = new PrintWriter(fileWriter);
for (String outputLine : lineList) {
out.println(outputLine);
}
out1.flush();
out1.close();
fileWriter.close();
}
Ok Because I couldn't let this question go unanswered here is a simple example of how you might do this using some built in classes:
import java.io.*;
import java.util.*;
public class q15664563 {
public static void main(String[] args) throws IOException {
String wordlist = "wordlist.txt";
if(args.length == 1 && args[0].toLowerCase().charAt(0) == 'l') {
//List Words
SortedSet<String> dictionary = load(wordlist);
for(String word : dictionary) {
System.out.println(word);
}
} else if(args.length == 2 && args[0].toLowerCase().charAt(0) == 'a') {
//Add Word
SortedSet<String> dictionary = load(wordlist);
dictionary.add(args[1].toLowerCase());
save(dictionary, wordlist);
} else {
System.err.println("Correct usage:");
System.err.println(" q15664563 LIST --lists all words");
System.err.println(" q15664563 ADD [word] --adds word to list");
}
}
private static void save(SortedSet<String> dictionary, String wordlist) throws IOException {
FileWriter file = new FileWriter(wordlist);
BufferedWriter writer = new BufferedWriter(file);
for(String word : dictionary) {
writer.append(word);
writer.newLine();
}
writer.close();
file.close();
}
private static SortedSet<String> load(String wordlist) throws IOException {
SortedSet<String> dictionary = new TreeSet<String>();
FileReader file = new FileReader(wordlist);
BufferedReader reader = new BufferedReader(file);
String word;
while((word = reader.readLine()) != null) {
dictionary.add(word);
}
reader.close();
file.close();
return dictionary;
}
}
Some things to point out with this code, reading and writing are two separate operations so to keep things clean it helps to put them in their own functions (this is a matter of opinion of course). Also, as is so often the case there are data types that will help you, and TreeSet is a great example of one. It implements the SortedSet interface and is alphabetical every time you iterate through ti (actually it's alphabetical every time you insert into it, something to keep in mind as the set grows in length). Given this property if you wanted to optimize you may only need to use TreeSet when the list might change it's alphabetic order (on insert). When listing you would read the file line by line knowing that it was in the correct order. If you did this then you would no longer have a generic load() method that you could use in both instances (something to consider when trading simplicity of design for performance).

Categories

Resources