Прочитайте файл, разделенный вкладкой, и поместите слова в ArrayList
Я занимаюсь самообучением, чтобы помочь мне больше узнать о Java, но я застрял в этом вопросе. У меня есть следующий файл txt:
Name Hobby
Susy eat fish
Anna gardening
Billy bowling with friends
Примечание. имя и хобби разделены вкладкой
Каков наилучший способ прочитать всю строку и поместить ее в arraylist (имя, хобби). Трудная часть состоит в том, что
eat fish or bowling with friends
имеет белые пробелы, и он должен быть помещен под один массив и, очевидно, я не могу его жестко кодировать. Вот мой текущий код:
public void openFile(){
try{
FileInputStream fstream = new FileInputStream("textfile.txt");
// use DataInputStream to read binary NOT text
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
ArrayList<String> names = new ArrayList<String>();
ArrayList<String> hobbies = new ArrayList<String>();
String lineJustFetched;
while ((lineJustFetched = br.readLine()) != null) {
String[] tokens = lineJustFetched.split(" \t");
Появилась ошибка:
java.lang.StringIndexOutOfBoundsException: индекс строки за пределами диапазона: -1
Я подозреваю, что подсчет индекса не очень полезен на вкладке.
Любая идея?
Ответы
Ответ 1
Хорошо, вам нужно сделать рецепт, показанный ниже:
- Создайте
BufferedReader
- Создайте
ArrayList<String>
- Начните чтение данных в переменную
String
с именем lineJustFetched
.
- Разделите
String
, вызвав lineJustFetched.split("\t");
- Итерации над созданным
String[]
. Убедитесь, что токен, который вы хотите ввести в ArrayList
, не ""
- Если нет, добавьте слово в
ArrayList
Вы указываете, что вам нужно разделить на основе значений \t
, поэтому пробелы не будут проблемой.
SSCCE
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
public class WordsInArray {
public static void main(String[] args) {
try{
BufferedReader buf = new BufferedReader(new FileReader("/home/little/Downloads/test"));
ArrayList<String> words = new ArrayList<>();
String lineJustFetched = null;
String[] wordsArray;
while(true){
lineJustFetched = buf.readLine();
if(lineJustFetched == null){
break;
}else{
wordsArray = lineJustFetched.split("\t");
for(String each : wordsArray){
if(!"".equals(each)){
words.add(each);
}
}
}
}
for(String each : words){
System.out.println(each);
}
buf.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
Выход
John
likes to play tennis
Sherlock
likes to solve crime
Ответ 2
Если вы разделили столбец Name и Hobby с вкладкой \t
, вы должны сделать что-то вроде этого (и не забудьте закрыть сканирование в конце):
public void readFile() throws FileNotFoundException{
Scanner scan = new Scanner(new File("D://a.txt"));
ArrayList<String> names = new ArrayList<String>();
ArrayList<String> hobbies = new ArrayList<String>();
while(scan.hasNext()){
String curLine = scan.nextLine();
String[] splitted = curLine.split("\t");
String name = splitted[0].trim();
String hobby = splitted[1].trim();
if(!"Name".equals(name)){
names.add(name);
}
if(!"Hobby".equals(hobby)){
hobbies.add(hobby);
}
}
System.out.println(names);
System.out.println(hobbies);
scan.close();
}
Ответ 3
Ибо другие все еще спотыкаются на это.
Используя Stream
API (Java 8), это можно сделать как
Это показывает
- Метод фильтра для фильтрации первого элемента заголовка из списка
- метод карты для сопоставления каждого элемента потока с другим элементом для нового потока.
package com.bhavya.stackoverflow.examples.q19575308;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.function.Predicate;
/**
* Java 8 Stream API to handle file reading.
*
* @author bhavya.work
*/
public class StreamTests {
public static void main(String[] args) {
try {
InputStream fileInputStream;
BufferedReader bufferedReader;
final String filepathInSamePackage = "textfile.txt";
//filter predicate
Predicate<String> filterFirstLine =
line -> !(
"Name".equals(line.split("\t", -1)[0])
&& "Hobby".equals(line.split("\t", -1)[1])
);
//Implementation 1 returns Arrays as asked.
System.out.println("==ArrayList==");
fileInputStream = StreamTests.class.getResourceAsStream(filepathInSamePackage);
bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));
bufferedReader
.lines()
.filter(filterFirstLine)
.map(s -> {
String[] splitStrings = s.split("\t", -1);
return Arrays.asList(splitStrings);
}).forEach(System.out::println);
//Implementation 2 returns HashMap as another example
fileInputStream = StreamTests.class.getResourceAsStream(filepathInSamePackage);
bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));
System.out.println("\n==HashMap==");
bufferedReader
.lines()
.filter(filterFirstLine)
.map(s -> {
String[] splitStrings = s.split("\t", -1);
HashMap<String, String> stringStringMap = new HashMap<>();
stringStringMap.put(splitStrings[0], splitStrings[1]);
return stringStringMap;
}).forEach(System.out::println);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
И вывод
==ArrayList==
[Susy, eat fish]
[Anna, gardening]
[Billy, bowling with friends]
==HashMap==
{Susy=eat fish}
{Anna=gardening}
{Billy=bowling with friends}
Ответ 4
Вы должны попробовать библиотеку commons-lang. Среди многих других полезных вещей вы можете разбить строку, используя разделитель:
String x="Billy bowling with friends";
String y[]=StringUtils.split(x, '\t');
Предполагая, что есть вкладка между Billy
и bowling
,
- y [0] содержит "Билли"
- у 1 содержится "боулинг с друзьями"
Ответ 5
Для будущих ссылок, когда вы просматриваете вкладку, существует разделитель, такой как "\ t" для вкладки.
Используйте это вместо .split("")
Также, когда вы ошиблись, потому что это означает, что символ не найден, следовательно, -1, поэтому при попытке сохранить его в массиве... -1 недействительно. (бросьте на это проверку)
Вы можете набросать свою программу F10 или F11..или другой ключ в зависимости от вашей IDE
Несколько советов