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();
}
Related
I have a file (file1.txt) containing:
word word word2 word word1
word2 word word 1
The other file (file2.txt) contains:
word1-replacement1
word2-replacement2
I need a method looking up if the words from file2 are contained in file1 and if they are contained replace those words with the replacement.
I already have following:
BufferedReader br = new BufferedReader(new FileReader("file2.txt"));
BufferedReader br2 = new BufferedReader(new FileReader("file1.txt"));
String line;
String line2;
while ((line = br.readLine()) != null) {
String vars[] = line.split("-");
String varname = vars[0];
String replacement = vars[1];
while ((line2 = br2.readLine()) != null) {
if(line2.contains(varname)) {
line2.replace(varname, replacement);
}
}
}
The problem with this code is, that it just reads only the first line of file1.
The final output should look like:
word word replacement2 word replacement1
replacement2 word replacement1
Thanks for your help :)
I suggest first reading in the second file into Java memory, and storing the data as a key value store in a hashmap. Then, iterate over the lines from the first file, and make any matching replacements.
Map<String, String> map = new HashMap<>();
String line = "";
try (BufferedReader br = new BufferedReader(new FileReader("file2.txt"))) {
while ((line = br.readLine()) != null) {
String[] parts = line.split("-");
map.put(parts[0], parts[1]);
}
}
catch (IOException e) {
// handle exception
}
try (BufferedReader br = new BufferedReader(new FileReader("file1.txt"))) {
while ((line = br.readLine()) != null) {
for (Map.Entry< String, String > entry : map.entrySet()) {
String pattern = "\\b" + entry.getKey() + "\\b";
line = line.replaceAll(pattern, entry.getValue());
// now record the updated line; printed to the console here for demo purposes
System.out.println(line);
}
}
}
catch (IOException e) {
// handle exception
}
Note carefully that I call String#replaceAll above with word boundaries around each term. This matters because, for example, without boundaries the term word1 would match something like aword1term, that is, it would match word1 even as a substring of some other word.
You can start by creating a Map of replacements like so:
public Map<String,String> getReplacements(File file) throws FileNotFoundException {
Map<String, String> replacementMap = new HashMap<>();
Scanner sc = new Scanner(file);
while(sc.hasNextLine()) {
String line = sc.nextLine();
String [] replacement = line.split("-");
String from = replacement[0];
String to = replacement[1];
replacementMap.put(from,to);
}
return replacementMap;
}
And then use the map to replace the words in the other file.
I've currently got a .txt file i need to read and output data based on what is inside. I've currently got the file to open and saved each line in the file into an ArrayList.
The .txt file is setup like this ;
2380213012999 1508434343432 david dead
4327482397488 7439857934858 john alive
3857948998099 2222783749887 martin killed kelly
3857948998099 2222783749887 john killed david
Current code ;
{
try {
File file = new File("input.txt");
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
StringBuffer stringBuffer = new StringBuffer();
String line;
ArrayList<String> txtline = new ArrayList<String>();
while ((line = bufferedReader.readLine()) != null) {
txtline.add(line);
System.out.println(txtline);
}
fileReader.close();
System.out.println(stringBuffer.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}
I'm just wondering if there is a way to sort each line of text by the 2nd large number, I've looked and I just can't seem to find anything. A point in the right direction or some guidance would be amazing as I'm currently stumped as I need to do this before i progress any further.
You can accomplish the task at hand by creating a stream of the list, passing in a Comparator object to the sorted method to define the sort key and then collect it into an ArrayList.
comparing numerically:
txtline = txtline.stream()
.sorted(Comparator.comparingLong((String e) -> Long.parseLong(e.split(" ")[1])))
.collect(Collectors.toCollection(ArrayList::new));
comparing by strings:
txtline = txtline.stream()
.sorted(Comparator.comparing((String e) -> e.split(" ")[1]))
.collect(Collectors.toCollection(ArrayList::new));
Put this after your while-loop
java.util.Collections.sort(txtLine, new Comparator<String>() {
public void compare(String lineA, String lineB) {
String wordA2 = lineA.split(" ")[1];
String wordB2 = lineB.split(" ")[1];
return wordA2.compareTo(wordB2);
}
});
Can be done more efficiently, but the code doesn't get much shorter than this (unless you use lambdas).
java.util.Collections.sort(txtLine, (String lineA, String lineB) -> {
String wordA2 = lineA.split(" ")[1];
String wordB2 = lineB.split(" ")[1];
return wordA2.compareTo(wordB2);
});
This question already has answers here:
Java reading a file into an ArrayList?
(13 answers)
Closed 6 years ago.
I would like to read in a file (game-words.txt) via a buffered reader into an ArrayList of Strings. I already set up the buffered reader to read in from game-words.txt, now I just need to figure out how to store that in an ArrayList. Thanks ahead for any help and patience!
Here is what I have so far:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOExecption;
class Dictionary{
String [] words; // or you can use an ArrayList
int numwords;
// constructor: read words from a file
public Dictionary(String filename){ }
BufferedReader br = null;
String line;
try {
br = new BufferedReader(new FileReader("game-words.txt"));
while ((line = br.readLine()) != null){
System.out.println(line);
}
} catch (IOExecption e) {
e.printStackTrace();
}
}
Reading strings into array:
Automatic:
List<String> strings = Files.readAllLines(Path);
Manual:
List<String> strings = new ArrayList<>();
while ((line = br.readLine()) != null){
strings.add(line);
}
Splitting lines to words (if one line contains several words):
for(String s : strings) {
String[] words = s.split(" "); //if words in line are separated by space
}
This could be helpful too:
class Dictionary{
ArrayList<String> words = new ArrayList<String>(); // or you can use an ArrayList
int numwords;String filename;
// constructor: read words from a file
public Dictionary(String filename){
this.filename =filename;
}
BufferedReader br = null;
String line;
try {
br = new BufferedReader(new FileReader("game-words.txt"));
while ((line = br.readLine()) != null){
words.add(line.trim());
}
} catch (IOExecption e) {
e.printStackTrace();
}
}
I have used trim which will remove the leading and the trailing spaces from the words if there are any.Also, if you want to pass the filename as a parameter use the filename variable inside Filereader as a parameter.
Yes, you can use an arrayList to store the words you are looking to add.
You can simply use the following to deserialize the file.
ArrayList<String> pList = new ArrayList<String>();
public void deserializeFile(){
try{
BufferedReader br = new BufferedReader(new FileReader("file_name.txt"));
String line = null;
while ((line = br.readLine()) != null) {
// assuming your file has words separated by space
String ar[] = line.split(" ");
Collections.addAll(pList, ar);
}
}
catch (Exception ex){
ex.printStackTrace();
}
}
My method takes a file, and tries to extract the text between the header ###Title### and closing ###---###. I need it to extract multiple lines and put each line into an array. But since readAllLines() converts all lines into an array, I don't know how to compare and match it.
public static ArrayList<String> getData(File f, String title) throws IOException {
ArrayList<String> input = (ArrayList<String>) Files.readAllLines(f.toPath(), StandardCharsets.US_ASCII);
ArrayList<String> output = new ArrayList<String>();
//String? readLines = somehow make it possible to match
System.out.println("Checking entry.");
Pattern p = Pattern.compile("###" + title + "###(.*)###---###", Pattern.DOTALL);
Matcher m = p.matcher(readLines);
if (m.matches()) {
m.matches();
String matched = m.group(1);
System.out.println("Contents: " + matched);
String[] array = matched.split("\n");
ArrayList<String> array2 = new ArrayList<String>();
for (String j:array) {
array2.add(j);
}
output = array2;
} else {
System.out.println("No matches.");
}
return output;
}
Here is my file, and I'm 100% sure that the compiler is reading the correct one.
###Test File###
Entry 1
Entry 2
Data 1
Data 2
Test 1
Test 2
###---###
The output says "No matches." instead of the entries.
You don't need regex for that. It's enough to loop through the array and compare items line by line, taking those between the start and end tags.
ArrayList<String> input = (ArrayList<String>) Files.readAllLines(f.toPath(), StandardCharsets.US_ASCII);
ArrayList<String> output = new ArrayList<String>();
boolean matched = false;
for (String line : input) {
if (line.equals("###---###") && matched) matched = false; //needed parentheses
if (matched) output.add(line);
if (line.equals("###Test File###") && !matched) matched = true;
}
As per your comment, if they are going to be in the same way as posted, then i don't think regex is needed for this requirement. You can read line by line and do a contains of '###'
public static void main(String args[])
{
ArrayList<String> dataList = new ArrayList<String>();
try{
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream("textfile.txt");
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
// this line will skip the header and footer with '###'
if(!strLine.contains("###");
dataList.add(strLine);
}
//Close the input stream
in.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
//Now dataList has all the data between ###Test File### and ###---###
}
You can also change the contains method parameter according to your requirement to ignore lines!
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.