I have txt file, which each row contains two words, for example:
USA 321
France 1009
...
Germany 902
How can I read this file by word in two-dimensional array? I have:
List<List<String>> temps = new ArrayList<>();
Scanner dataScanner = new Scanner(dataFile);
while (dataScanner.hasNextLine()) {
Scanner rowScanner = new Scanner(dataScanner.nextLine());
temps.add(new ArrayList<>(2));
while (rowScanner.hasNextLine()) {
...
}
}
I would do it like this assuming your code works
List<List<String>> temps = new ArrayList<>();
Scanner dataScanner = new Scanner(dataFile);
while (dataScanner.hasNextLine()) {
String[] data = dataScanner.nextLine().split(" ");
temps.add(new ArrayList<>(Arrays.asList(data[0],data[1]));
}
This takes the current line and splits it at a space character.
Afterwards it creates a list with the two elements and adds it to your temps list
If you want absolutely use Scanner :
List<List<String>> temps = new ArrayList<>();
Scanner dataScanner = new Scanner("a b\nc d\ne f\n");
while (dataScanner.hasNextLine()) {
Scanner rowScanner = new Scanner(dataScanner.nextLine());
List<String> datas=new ArrayList<>(2);
temps.add(datas);
while (rowScanner.hasNext("[^\\s]+")) {
datas.add(rowScanner.next("[^\\s]+"));
}
}
My advice is to ALWAYS separate different functionalities in different functions. The code becomes easier to read, easier to mantain and reusable:
public static List<String> readFileLineByLine(String file) {
List<String> lines = new ArrayList<>();
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
temps.add(scanner.nextLine());
}
return lines;
}
public static List<MyData> parseLines(List<String> lines) {
List<MyData> list = new ArrayList<>();
for (String line : lines) {
String[] data = line.split(" ");
list.add(new MyData(data[0], data[1]));
}
return list;
}
(Use List<String> as MyData if you need to)
I'm a big fan of Scanner, but in this case you can get by reading line-by-line and using String.split. This becomes quite simple using streams. If you want to read into a two-dimensional array, you can do this:
try (Stream<String> lines = Files.lines(Paths.get(FILENAME), UTF_8)) {
String[][] result = lines.map(s -> s.split("\\s+"))
.toArray(String[][]::new);
}
Or if you want nested Lists, you can do this:
try (Stream<String> lines = Files.lines(Paths.get(FILENAME), UTF_8)) {
List<List<String>> result = lines.map(s -> s.split("\\s+"))
.map(Arrays::asList)
.collect(toList());
System.out.println(result);
}
Related
I've read these two stack overflow posts: this one and this one. I've followed the answers and am still getting no where.
I'm trying to read in a text file (this one) and store it in an ArrayList. But when i go ahead and print the contents of the ArrayList to the console, nothing is returned...
Any help would be appreciated.
public static void main(String[] args) throws IOException {
ArrayList<Integer> test = new ArrayList<Integer>();
Scanner textFileOne = new Scanner(new File("ChelseaVector.txt"));
while (textFileOne.hasNext()) {
if(textFileOne.hasNextInt()) {
test.add(textFileOne.nextInt());
} else {
textFileOne.next();
}
}
textFileOne.close();
System.out.println(test);
}
You need to skip the [ character at the beginning of the file, and define your delimiter as ]:
Scanner textFileOne =
new Scanner(new File("ChelseaVector.txt")).useDelimiter(", ").skip("\\[");
List<String> originalFile = new ArrayList<>(Files.readAllLines(Paths.get("ChelseaVector.txt")));
List<Integer> formattedFile = new ArrayList<>();
for (String line : originalFile ) {
String newLine = line.replaceAll("[", "").replaceAll("]", "").replaceAll(" ", "");
List<String> numbers = Arrays.asList(String.join(","));
formattedFile.addAll(numbers);
}
System.out.println(formattedFile);
You can do like this
public static void main(String[] args) throws IOException {
ArrayList<Integer> test = new ArrayList<Integer>();
Scanner textFileOne = new Scanner(new File("ChelseaVector.txt")).useDelimiter(",");
while (textFileOne.hasNext()) {
if (textFileOne.hasNextInt()) {
test.add(textFileOne.nextInt());
} else {
int number=Integer.parseInt(textFileOne.next().replaceAll("[\\[\\]]","").trim());
test.add(number);
}
}
textFileOne.close();
System.out.println(test);
}
Since your file contains one line only, you shouldn't be using a loop in my opinion.
The following code should work if you're using java-8
String[] strings = Files.lines(Paths.get("ChelseaVector.txt")).findFirst().split("\\D+");
List<Integer> ints = Arrays.stream(strings).map(Integer::valueOf).collect(Collectors.toList());
public class CompareCSV {
public static void main(String args[]) throws FileNotFoundException, IOException {
String path = "C:\\csv\\";
String file1 = "file1.csv";
String file2 = "file2.csv";
String file3 = "file3.csv";
ArrayList<String> al1 = new ArrayList<String>();
ArrayList<String> al2 = new ArrayList<String>();
BufferedReader CSVFile1 = new BufferedReader(new FileReader("/C:/Users/bida0916/Desktop/macro.csv"));
String dataRow1 = CSVFile1.readLine();
while (dataRow1 != null) {
String[] dataArray1 = dataRow1.split(",");
for (String item1 : dataArray1) {
al1.add(item1);
}
dataRow1 = CSVFile1.readLine();
}
CSVFile1.close();
BufferedReader CSVFile2 = new BufferedReader(new FileReader("C:/Users/bida0916/Desktop/Deprecated.csv"));
String dataRow2 = CSVFile2.readLine();
while (dataRow2 != null) {
String[] dataArray2 = dataRow2.split(",");
for (String item2 : dataArray2) {
al2.add(item2);
}
dataRow2 = CSVFile2.readLine();
}
CSVFile2.close();
for (String bs : al2) {
al1.remove(bs);
}
int size = al1.size();
System.out.println(size);
try {
FileWriter writer = new FileWriter("C:/Users/bida0916/Desktop/NewMacro.csv");
while (size != 0) {
size--;
writer.append("" + al1.get(size));
writer.append('\n');
}
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I want to compare two csv files in java and want to have the complete details removed of one csv file from the other by comparing the first column of both the files. Currently I am getting a csv file with one column only having all details jumbled up.
You are adding all values of all columns to a single list, that's why you get the mess in your output:
ArrayList<String> al1=new ArrayList<String>();
//...
String[] dataArray1 = dataRow1.split(",");
for (String item1:dataArray1)
{
al1.add(item1);
}
Add the complete string array from your file to your list, then you can access your data in a structured way:
List<String[]> al1 = new ArrayList<>();
//...
String[] dataArray1 = dataRow1.split(",");
al1.add(dataArray1);
But for removal of rows I'd recommend to use Maps for faster access, where the key is the element on which you decide which row to delete and the value is the full row from your cvs file:
Map<String, String> al1 = new HashMap<>(); // or LinkedHashMap if row order is relevant
//...
String[] dataArray1 = dataRow1.split(",");
al1.put(dataArray1[0], dataRow1);
But be aware, that if two rows in a file contain the same value in the first column, only one will be preserved. If that's possible you might need to adopt that solution to store the data in a Map<String, Set<String>> or Map<String, List<String>>.
At this point I'd like to recommend to extract the file-reading to a separate method, which you can reuse to read both of your input-files and reduce duplicate code:
Map<String, String> al1 = readInputCsvFile(file1);
Map<String, String> al2 = readInputCsvFile(file2);
For the deletion of the lines which shall be removed, iterate over the key set of one of the maps and remove the entry from the other:
for (String key : al2.keySet()) {
al1.remove(key);
}
And for writing your output file, just write the row read from the original file as stored in the 'value' of your map.
for (String dataRow : al1.values()) {
writer.append(dataRow);
writer.append('\n');
}
EDIT
If you need to perform operations based on other data columns you should rather store the 'split-array' in the map instead of the full-line string read from the file. Then you have all data columns separately available:
Map<String, String[]> al2 = new HashMap<>();
//...
String[] dataArray2 = dataRow2.split(",");
al2.put(dataArray2[0], dataArray2);
You might then, e.g. add a condition for deleting:
for (Entry<String, String[]> entry : al2.entrySet()) {
String[] data = entry.getValue();
if ("delete".equals(data[17])) {
al1.remove(entry.getKey());
}
}
For writing your output file you have to rebuild the csv-format.
I'd recommend to use Apache commons-lang StringUtils for that task:
for (String[] data : al1.values()) {
writer.append(StringUtils.join(data, ","));
writer.append('\n');
}
I have the following data stored in a .txt file:
one,1
two,2
three,3
......
I want to store the information in an array with the following structure:
[one,1,two,2....]
Here is my code so far:
public Shortener( String inAbbreviationsFilePath ) throws FileNotFoundException {
Scanner s = new Scanner(new File(inAbbreviationsFilePath));
ArrayList<String> list = new ArrayList<String>();
while (s.hasNext()){
list.add(s.next());
}
abbreviations = list.toArray(new String[list.size()]);
s.close();
}
My problem is that I cant get the array to be stored so that one and 1 are in different positions. i.e at the moment the array is structured like this [one1,two2,...].
Thanks for help in advance
You have to split each line by the coma and add two parts of it to your result list:
public Shortener( String inAbbreviationsFilePath ) throws FileNotFoundException {
Scanner s = new Scanner(new File(inAbbreviationsFilePath));
ArrayList<String> list = new ArrayList<String>();
while (s.hasNext()) {
//HERE
String line = s.next();
String[] lineSplit = line.split(","); //split into two tokens
list.add(lineSplit[0]); //word
list.add(lineSplit[1]); //number
}
abbreviations = list.toArray(new String[list.size()]);
s.close();
}
Use this instead of your while loop,
String str;
String []st;
while ((str=s.nextLine())!=null){
st=str.split(",");
list.add(st[0]);
list.add(st[1]);
}
try this
Scanner s = new Scanner(new File...
s.useDelimiter("\\s+|,");
I'm having trouble scanning a given file for certain words and assigning them to variables, so far I've chosen to use Scanner over BufferedReader because It's more familiar. I'm given a text file and this particular part I'm trying to read the first two words of each line (potentially unlimited lines) and maybe add them to an array of sorts. This is what I have:
File file = new File("example.txt");
Scanner sc = new Scanner(file);
while (sc.hasNextLine()) {
String line = sc.nextLine();
String[] ary = line.split(",");
I know It' a fair distance off, however I'm new to coding and cannot get past this wall...
An example input would be...
ExampleA ExampleAA, <other items seperated by ",">
ExampleB ExampleBB, <other items spereated by ",">
...
and the proposed output
VariableA = ExampleA ExampleAA
VariableB = ExampleB ExampleBB
...
You can try something like this
File file = new File("D:\\test.txt");
Scanner sc = new Scanner(file);
List<String> list =new ArrayList<>();
int i=0;
while (sc.hasNextLine()) {
list.add(sc.nextLine().split(",",2)[0]);
i++;
}
char point='A';
for(String str:list){
System.out.println("Variable"+point+" = "+str);
point++;
}
My input:
ExampleA ExampleAA, <other items seperated by ",">
ExampleB ExampleBB, <other items spereated by ",">
Out put:
VariableA = ExampleA ExampleAA
VariableB = ExampleB ExampleBB
To rephrase, you are looking to read the first 2 words of a line (everything before the first comma) and store it in a variable to process further.
To do so, your current code looks fine, however, when you grab the line's data, use the substring function in conjunction with indexOf to just get the first part of the String before the comma. After that, you can do whatever processing you want to do with it.
In your current code, ary[0] should give you the first 2 words.
public static void main(String[] args)
{
File file = new File("example.txt");
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
String line = "";
List l = new ArrayList();
while ((line = br.readLine()) != null) {
System.out.println(line);
line = line.trim(); // remove unwanted characters at the end of line
String[] arr = line.split(",");
String[] ary = arr[0].split(" ");
String firstTwoWords[] = new String[2];
firstTwoWords[0] = ary[0];
firstTwoWords[1] = ary[1];
l.add(firstTwoWords);
}
Iterator it = l.iterator();
while (it.hasNext()) {
String firstTwoWords[] = (String[]) it.next();
System.out.println(firstTwoWords[0] + " " + firstTwoWords[1]);
}
}
How do I convert this ArrayList's value into an array? So it can look like,
String[] textfile = ... ;
The values are Strings (words in the text file), and there are more than a 1000 words. In this case I cannot do the, words.add("") 1000 times. How can I then put this list into an array?
public static void main(String[]args) throws IOException
{
Scanner scan = new Scanner(System.in);
String stringSearch = scan.nextLine();
List<String> words = new ArrayList<String>(); //convert to array
BufferedReader reader = new BufferedReader(new FileReader("File1.txt"));
String line;
while ((line = reader.readLine()) != null) {
words.add(line);
}
You can use
String[] textfile = words.toArray(new String[words.size()]);
Relevant Documentation
List#toArray(T[])
words.toArray() should work fine.
List<String> words = new ArrayList<String>();
String[] wordsArray = (String[]) words.toArray();
you can use the toArray method of Collection such as shown here
Collection toArray example
List<String> words = new ArrayList<String>();
words.add("w1");
words.add("w2");
String[] textfile = new String[words.size()];
textfile = words.toArray(textfile);