Java 读取由制表符分隔的文件并将单词放入 ArrayList
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19575308/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Read a file separated by tab and put the words in an ArrayList
提问by user2891092
I am doing a self learning exercise to help me understand more about Java, but I am stuck at this question. I have the following txt file:
我正在做一个自学练习,以帮助我更多地了解 Java,但我被困在这个问题上。我有以下txt文件:
Name Hobby
Susy eat fish
Anna gardening
Billy bowling with friends
Note: name and hobby are separated by tab
注:姓名和爱好由制表符分隔
What is the best way to read all the line and put it in arraylist(name,hobby). The tricky part is that
阅读所有行并将其放入 arraylist(name,hobby) 的最佳方法是什么。棘手的部分是
eat fish or bowling with friends
has white spaces and it must be put under one array and obviously I cannot hardcode it. Here is my current code:
有空格,它必须放在一个数组下,显然我不能对其进行硬编码。这是我当前的代码:
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");
I got an error:
我有一个错误:
java.lang.StringIndexOutOfBoundsException: String index out of range: -1
java.lang.StringIndexOutOfBoundsException:字符串索引超出范围:-1
I suspect counting the index is not very useful on a tab. Any idea?
我怀疑在选项卡上计算索引不是很有用。任何的想法?
采纳答案by Little Child
Alright, you need to do the recipe shown below:
好的,您需要执行如下所示的食谱:
- Create a
BufferedReader
- Create an
ArrayList<String>
- Start reading data into a
String
variable namedlineJustFetched
. - Split the
String
by callinglineJustFetched.split("\t");
- Iterate over the
String[]
produced. Check if the token you want to enter into theArrayList
is not""
- If not, add the word to the
ArrayList
- 创建一个
BufferedReader
- 创建一个
ArrayList<String>
- 开始将数据读入
String
名为的变量lineJustFetched
。 String
通过调用拆分lineJustFetched.split("\t");
- 迭代
String[]
产生的。检查您要输入的令牌是否ArrayList
不是""
- 如果没有,请将该词添加到
ArrayList
You specify that you need to split based on \t
values so white spaces won't be an issue.
您指定需要根据\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();
}
}
}
Output
输出
John
likes to play tennis
Sherlock
likes to solve crime
回答by windjammer
You should try the commons-lang library. Among many other useful things you can split a string using a delimiter:
您应该尝试使用commons-lang 库。在许多其他有用的东西中,您可以使用分隔符拆分字符串:
String x="Billy bowling with friends";
String y[]=StringUtils.split(x, '\t');
Assuming there is a tab between Billy
and bowling
,
假设Billy
和之间有一个制表符bowling
,
- y[0] contains "Billy"
- y1contains "bowling with friends"
- y[0] 包含“比利”
- y 1包含“与朋友打保龄球”
回答by Seifo84
For future references when you parse out tab there is a delimiter such as "\t" for tab. Use that instead of .split(" ")
对于将来解析制表符时的参考,制表符有一个分隔符,例如“\t”。使用它而不是 .split(" ")
Also, when your error is thrown because it means no character is found, hence the -1, so when you try to store it in an Array... -1 is not valid. (throw in a check for that)
此外,当您的错误被抛出时,因为这意味着找不到字符,因此是 -1,因此当您尝试将其存储在数组中时...-1 无效。(为此投入一张支票)
You can step throw your program F10 or F11..or some other key depending on your IDE
您可以根据您的 IDE 逐步抛出程序 F10 或 F11 .. 或其他一些键
Just some tips
只是一些提示
回答by Arya
If you separated Name and Hobby column with tab \t
, you should do something like this (and don't forget to close scan at end):
如果你用 tab 分隔 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();
}
回答by bhavya.work
For others still stumbling upon this.
对于其他人仍然绊倒这一点。
Using Stream
API (Java 8), this can be done as
使用Stream
API (Java 8),这可以作为
This shows
由此可见
- Filter method to filter the first header element from the list
- map method to map each element in stream to another element for new stream.
- 过滤方法从列表中过滤第一个标题元素
- map 方法将流中的每个元素映射到新流的另一个元素。
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();
}
}
}
And the output
和输出
==ArrayList==
[Susy, eat fish]
[Anna, gardening]
[Billy, bowling with friends]
==HashMap==
{Susy=eat fish}
{Anna=gardening}
{Billy=bowling with friends}