我有一个包含以下内容的.txt
文件:"17.23;12.1;20.34;88.23523;"
。我想把这个文件读成ArrayList
。并最终打印ArrayList
(并最终打印最小值和最大值,但我认为解决此问题后不会出现问题(。
但我只得到输出";[]">
我做错了什么?我已经为此挣扎了15个多小时,浏览了这里、youtube、课程书。。。
我的代码:
public static void main(String[] args) throws IOException {
File myFile = new File("text.txt");
Scanner scan = new Scanner(myFile);
ArrayList<Double> aList = new ArrayList<>();
while (scan.hasNextDouble()) {
double nextInput = scan.nextDouble();
if (nextInput != 0) {
break;
}
aList.add(nextInput);
}
System.out.println(alist);
}
您应该配置扫描仪,使其接受:
;
作为分隔符,
作为十进制分隔符
工作代码为:
File myFile = new File("input.txt");
// Swedish locale uses ',' as a decimal separator
Scanner scan = new Scanner(myFile).useDelimiter(";").useLocale(Locale.forLanguageTag("sv-SE"));
ArrayList<Double> aList = new ArrayList<>();
while (scan.hasNextDouble()) {
double nextInput = scan.nextDouble();
aList.add(nextInput);
}
System.out.println(aList);
带输出[17.23, 12.1, 20.34, 88.23523]
Scanner
的工作原理是将输入拆分为令牌,其中令牌由空格分隔(默认情况下(。由于文本中没有空格,第一个/唯一的令牌是整个文本,并且由于该文本不是有效的double
值,hasNextDouble()
返回false
。
两种解决方法:
-
将令牌分隔符更改为
;
:scan.useDelimiter(";");
-
使用
BufferedReader
读取文件并使用split()
:String filename = "text.txt"; try (BufferedReader in = Files.newBufferedReader(Paths.get(filename))) { for (String line; (line = in.readLine()) != null; ) { String[] tokens = line.split(";"); // code here } }
现在将产生以下标记:17,23
、12,1
、20,34
、88,23523
。
不幸的是,这些值都不是有效的double
值,因为它们使用特定于区域设置的格式,即小数点是,
,而不是.
。
也就是说,如果你一直使用Scanner
,你就不能使用hasNextDouble()
和nextDouble()
,如果你改为使用split()
,你就无法使用Double.parseDouble()
。
您需要使用NumberFormat
来解析特定于区域设置的数字格式。由于";Uppgift";看起来像瑞典语,我们可以使用NumberFormat.getInstance(Locale.forLanguageTag("sv-SE"))
,如果您的默认语言环境是瑞典,则可以简单地使用NumberFormat.getInstance()
。
String filename = "text.txt";
try (BufferedReader in = Files.newBufferedReader(Paths.get(filename))) {
NumberFormat format = NumberFormat.getInstance(Locale.forLanguageTag("sv-SE"));
for (String line; (line = in.readLine()) != null; ) {
List<Double> aList = new ArrayList<>();
for (String token : line.split(";")) {
double value = format.parse(token).doubleValue();
aList.add(value);
}
System.out.println(aList); // Prints: [17.23, 12.1, 20.34, 88.23523]
}
}
您只需更改分隔符即可完成此操作。这是通过从字符串中读取来实现的,但也可以从文件中读取。将值放入某个数据结构中取决于您。这假定您的默认区域设置使用","作为小数点。
String str = "17,23;12,1;20,34;88,23523;";
Scanner scan = new Scanner(str);
scan.useDelimiter("[;]+");
while(scan.hasNextDouble()) {
System.out.println(scan.nextDouble());
}
打印
17.23
12.1
20.34
88.23523
由于文件中有用分号分隔的数字,因此默认情况下无法使用scan.hasNextDouble()
读取这些数字。然而,有很多方法可以做到这一点,例如
- 覆盖默认分隔符
- 将一行作为字符串读取,并在分号上拆分后处理其中的每个数字
选项1:
scan.useDelimiter(";")
请注意,由于您的文件使用逗号而不是点作为十进制符号,因此可以使用默认值为Locale
的文件。
scan.useLocale(Locale.FRANCE);
此外,代码中的以下代码块将导致循环在读取第一个数字后终止,因为文件中的第一个数字不等于零。只需删除这些行即可获得所需结果:
if (nextInput != 0) {
break;
}
选项2:
读取一行,将其拆分为分号,将逗号替换为点,将所得数组中的每个元素解析为Double
,并将其存储到aList
中。
演示:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
File myFile = new File("file.txt");
Scanner scan = new Scanner(myFile);
List<Double> aList = new ArrayList<>();
while (scan.hasNextLine()) {
String nextInput = scan.nextLine();
String[] arr = nextInput.split(";");
for (String s : arr) {
aList.add(Double.valueOf(s.replace(",", ".")));
}
}
System.out.println(aList);
}
}
输出:
[17.23, 12.1, 20.34, 88.23523]
将逗号替换为句点的另一种方法是使用NumberFormat
,如下所示:
import java.io.File;
import java.io.FileNotFoundException;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException, ParseException {
File myFile = new File("file.txt");
Scanner scan = new Scanner(myFile);
NumberFormat format = NumberFormat.getInstance(Locale.FRANCE);
List<Double> aList = new ArrayList<>();
while (scan.hasNextLine()) {
String nextInput = scan.nextLine();
String[] arr = nextInput.split(";");
for (String s : arr) {
aList.add(format.parse(s).doubleValue());
}
}
System.out.println(aList);
}
}