text File Dictionary Java - 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).

Related

How to remove the duplicate string?

In my code I have two files in my drive those two files have some text and I want to display those string in the console and also remove the repeated string and display the repeated string once rather than displaying it twice.
Code:
public class read {
public static void main(String[] args) {
try{
File file = new File("D:\\file1.txt");
FileReader fileReader = new FileReader(file);
BufferedReader br = new BufferedReader(fileReader);
StringBuffer stringBuffer = new StringBuffer();
String line;
while((line = br.readLine()) != null){
stringBuffer.append(line);
stringBuffer.append("\n");
}
fileReader.close();
System.out.println("Contents of file1:");
String first = stringBuffer.toString();
System.out.println(first);
File file1 = new File("D:\\file2.txt");
FileReader fileReader1 = new FileReader(file1);
BufferedReader br1 = new BufferedReader(fileReader1);
StringBuffer stringBuffer1 = new StringBuffer();
String line1;
while((line1 = br1.readLine()) != null){
stringBuffer1.append(line1);
stringBuffer1.append("\n");
}
fileReader1.close();
System.out.println("Contents of file2:");
String second = stringBuffer1.toString();
System.out.println(second);
System.out.println("answer:");
System.out.println(first+second);
}catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
Output is:
answer:
hi hello
how are you
hi ya
i am fine
But I want to compare both the strings and if the same string repeated then that string should be displayed once.
Output I expect is like this:
answer:
hi hello
how are you
ya
i am fine
Where the "hi" is found in both the strings so that I need to delete the one duplicate string.
How can I do that please help.
Thanks in advance.
You can pass your lines through this method to parse out duplicate words:
// store unique previous words
static Set<String> words = new HashSet<>();
static String removeDuplicateWords(String line) {
StringJoiner sj = new StringJoiner(" ");
// split on whitespace to get distinct words
for (String word : line.split("\\s+")) {
// try to add word to the set
if (words.add(word)) {
// if the word was added (=not seen before), append to the result
sj.add(word);
}
}
return sj.toString();
}

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);
}

read from file and write some parts in another file

I have to read from a text file and format the input. I'm new to java reading from files, and I don't know how to work with just some parts of what I read
Here is the initial file: http://pastebin.com/D0paWtAd
And I have to write in another file the following output:
Average,Joe,44,31,18,12,9,10
I've managed just to take everything from the file and print it to output. I would need help just in taking the output I need and print it to the screen. Any help is appreciated.
This is what I wrote up to now:
public class FileParsing {
public static String
read(String filename) throws IOException {
BufferedReader in = new BufferedReader(new FileReader("C:\\Users\\Bogdi\\Desktop\\example.txt"));
String s;
StringBuilder sb = new StringBuilder();
while((s = in.readLine())!= null) sb.append(s + "\n");
in.close();
return sb.toString();
}
If your goal is to do the specified output in another file you don't need to first get the content of your file in a StringBuilder before processing it, you can append the processed datas directly in a StringBuilder then you can write the result in a file. Here is an example that would work for the given file but you may have to modify it if the keys change in the future:
The following method will correctly process the datas from your file
public static String read(String filename) throws IOException {
BufferedReader in = new BufferedReader(new FileReader(filename));
String s;
StringBuilder sb = new StringBuilder();
while((s = in.readLine())!= null) {
String[] split1 = s.split("=");
if (split1[0].equals("name")) {
StringTokenizer tokenizer = new StringTokenizer(split1[1]);
sb.append(tokenizer.nextToken());
sb.append(",");
sb.append(tokenizer.nextToken());
sb.append(",");
} else if (split1[0].equals("index")) {
sb.append(split1[1] + ",");
} else if (split1[0].equals("FBid")) {
sb.append(split1[1]);
} else {
StringTokenizer tokenizer = new StringTokenizer(split1[1]);
String wasted = tokenizer.nextToken();
sb.append(tokenizer.nextToken() + ",");
}
}
in.close();
return sb.toString();
}
The next method will read any string to a file
public static void writeStringToFile(String string, String filePath) throws IOException {
BufferedWriter writer = new BufferedWriter(
new FileWriter(
new File(filePath)
)
);
writer.write(string);
writer.newLine();
writer.flush();
writer.close();
}
And here is a simple tests (File1.txt contains the datas from the file you shared on paste bin and I write them in another file)
public static void main(String[] args) throws Exception {
String datas = read("C:\\Tests\\File1.txt");
System.out.println(datas);
writeStringToFile(datas, "C:\\Tests\\FileOuput.txt" );
}
It will produce the exact output that you are expecting
[EDIT] #idk, apparently you have an exception executing my example, while it is working fine for me. That could only mean there is an error at data level. Here is the data sample that I used (and I believe I exactly copy the datas you shared)
And here is the result:
Good to know you are using "StringBuilder" component instead being concatenating your String values, way to go :).
More than knowledge on the Java.IO API to work with files, you will need some logic to get the results you expect. Here I came with an approach that could help you, not perfect, but can point you on how to face this problem.
//Reference to your file
String myFilePath = "c:/dev/myFile.txt";
File myFile = new File(myFilePath);
//Create a buffered reader, which is a good start
BufferedReader breader = new BufferedReader(new FileReader(myFile));
//Define this variable called line that will evaluate each line of our file
String line = null;
//I will use a StringBuilder to append the information I need
StringBuilder appender = new StringBuilder();
while ((line = breader.readLine()) != null) {
//First, I will obtain the characters after "equals" sign
String afterEquals = line.substring(line.indexOf("=") + 1, line.length());
//Then, if it contains digits...
if (afterEquals.matches(".*\\d+.*")) {
//I will just get the digits from the line
afterEquals = afterEquals.replaceAll("\\D+","");
}
//Finally, append the contents
appender.append(afterEquals);
appender.append(",");//This is the comma you want to include
}
//I will delete the last comma
appender.deleteCharAt(appender.length() - 1);
//Close the reader...
breader.close();
//Then create a process to write the content
BufferedWriter myWriter = new BufferedWriter(new FileWriter(new File("myResultFile.txt")));
//Write the full contents I get from my appender :)
myWriter.write(appender.toString());
//Close the writer
myWriter.close();
}
Hope this can help you. Happy coding!

how to edit my compare method

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();
}

Java read in a text file and then separate into separate arrays

I have a text file which is read in. It has delimeters which are <.> . There is a main subject then there are three paragraphs. Lets say title, section1, section2, section3, and then the next article.
How can I store the data so that ArrayList one will have all the titles, ArrayList 2 will have all the section1 information, etc.? I want be able to output these arrays.
E.g.:
Large storm on its way.
about the large storm
statics on storms
conclusions about storms
The example above shows what one record would look like.
public void read()
{
try
{
FileReader fr = new FileReader(file_path);
BufferedReader br = new BufferedReader(fr);
String s = "";
// keep going untill there is no input left and then exit
while((s = br.readLine()) != null)
{ }
fr.close();
}
catch (Exception e)
{
System.err.println("Error: read() " + e.getMessage());
}
}
public static void main(String [] args)
{
Reader reader = new ResultsReader("C:/data.txt");
reader.read();
String output = ((ResultsReader)reader).getInput();
String str = "title<.>section1<.>section2<.>";
String data[] = str.split("<.>");
}
I am not sure how to store the data in separate ArrayLists so that they can be traversed.
You cannot create arrays and put the data into them, because you don't know how large to create the arrays. So, use a list instead and then turn them into arrays after you have finished reading the file:
List tilesList = new ArrayList<String>();
// etc.
FileReader fr = new FileReader(file_path);
BufferedReader br = new BufferedReader(fr);
String s = null // I think this should be null, so that if there are no lines,
// you don't have problems with str.split();
while((s = br.readLine()) != null) {
String[] line = str.split("<.>");
tilesList.add(line[1]);
// etc.
}
fr.close();
String[] tiles = tilesList.toArray(new String[tilesList.size()]);
// etc.

Categories

Resources