将一个包含doubles的.txt文件转换为ArrayList



我有一个包含以下内容的.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);
}

您应该配置扫描仪,使其接受:

  1. ;作为分隔符
  2. ,作为十进制分隔符

工作代码为:

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,2312,120,3488,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. 覆盖默认分隔符
  2. 将一行作为字符串读取,并在分号上拆分后处理其中的每个数字

选项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);
}
}

最新更新