Je fais un exercice d'auto-apprentissage pour m'aider à mieux comprendre Java, mais je suis bloqué à cette question. J'ai le fichier txt suivant:
Name Hobby
Susy eat fish
Anna gardening
Billy bowling with friends
Remarque: le nom et le passe-temps sont séparés par des tabulations
Quelle est la meilleure façon de lire toute la ligne et de la mettre en liste (nom, passe-temps). La partie délicate est que
eat fish or bowling with friends
a des espaces blancs et il doit être placé sous un tableau et évidemment je ne peux pas le coder en dur. Voici mon code actuel:
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");
J'ai une erreur:
Java.lang.StringIndexOutOfBoundsException: index de chaîne hors limites: -1
Je soupçonne que compter l’index n’est pas très utile sur un onglet. Une idée?
Bon, vous devez faire la recette ci-dessous:
BufferedReader
ArrayList<String>
String
nommée lineJustFetched
. String
en appelant lineJustFetched.split("\t");
String[]
produit. Vérifiez si le jeton que vous souhaitez entrer dans la variable ArrayList
n'est pas ""
ArrayList
Vous indiquez que vous devez fractionner selon les valeurs de \t
afin que les espaces ne soient pas un problème.
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();
}
}
}
Sortie
John
likes to play tennis
Sherlock
likes to solve crime
Si vous avez séparé la colonne Nom et Loisir avec l'onglet \t
, vous devriez faire quelque chose comme ceci (et n'oubliez pas de fermer l'analyse à la fin):
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();
}
Pour d'autres encore trébucher sur cela.
À l'aide de Stream
API (Java 8), vous pouvez le faire
Ceci montre
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();
}
}
}
Et la sortie
==ArrayList==
[Susy, eat fish]
[Anna, gardening]
[Billy, bowling with friends]
==HashMap==
{Susy=eat fish}
{Anna=gardening}
{Billy=bowling with friends}
Vous devriez essayer la bibliothèque commons-lang . Parmi beaucoup d'autres choses utiles, vous pouvez diviser une chaîne à l'aide d'un délimiteur:
String x="Billy bowling with friends";
String y[]=StringUtils.split(x, '\t');
En supposant qu'il y ait un onglet entre Billy
et bowling
,
Pour les références futures lorsque vous analysez l'onglet, il existe un délimiteur tel que "\ t" pour l'onglet. Utilisez-le plutôt que .split ("")
En outre, lorsque votre erreur est renvoyée car cela signifie qu'aucun caractère n'est trouvé, d'où le -1, donc lorsque vous essayez de le stocker dans un tableau ... -1 n'est pas valide. (jetez un chèque pour cela)
Vous pouvez lancer votre programme F10 ou F11..ou une autre clé en fonction de votre IDE
Quelques conseils