Tengo un archivo .txt con este contenido: "17.23;12.1;20.34;88.23523;" . Quiero leer este archivo como dobles en un ArrayList . Y eventualmente imprima ArrayList (y eventualmente imprima el mínimo y el máximo, pero no creo que eso sea un problema después de resolver esto).
Pero solo obtengo el resultado "[]".
¿Qué estoy haciendo mal? He estado luchando con esto durante más de 15 horas vergonzosas, busqué aquí, youtube, libros de texto...
Mi código:
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); }Debe configurar su escáner para que acepte:
; como delimitador, como separador decimalEl código de trabajo es:
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); Con salida [17.23, 12.1, 20.34, 88.23523]
Scanner funciona dividiendo la entrada en tokens, donde los tokens están separados por espacios en blanco (de forma predeterminada). Dado que no hay espacios en blanco en el texto, el primer/único token es el texto completo, y dado que ese texto no es un valor double válido, hasNextDouble() devuelve false .
Dos formas de arreglar eso:
Cambie el separador de fichas a ; :
scan.useDelimiter(";"); Lea el archivo con BufferedReader y use 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 } } Eso ahora dará como resultado los siguientes tokens: 17,23 , 12,1 , 20,34 , 88,23523 .
Desafortunadamente, ninguno de ellos son valores double válidos, ya que utilizan un formato específico de la configuración regional, es decir, el punto decimal es , , no . .
Lo que significa que si siguió usando Scanner , no puede usar hasNextDouble() y nextDouble() , y si cambió para usar split() , no puede usar Double.parseDouble() .
Debe usar un NumberFormat para analizar formatos de números específicos de la configuración regional. Dado que "Uppgift" parece sueco, podemos usar NumberFormat.getInstance(Locale.forLanguageTag("sv-SE")) , o simplemente NumberFormat.getInstance() si su configuración regional predeterminada es Suecia.
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] } }Dado que su archivo tiene números separados por un punto y coma, no podrá leerlos usando scan.hasNextDouble() de forma predeterminada. Sin embargo, hay muchas maneras de hacerlo, por ejemplo
Opción 1:
scan.useDelimiter(";") Tenga en cuenta que dado que su archivo tiene la coma en lugar del punto como símbolo decimal, puede usar una configuración Locale en la que sea la predeterminada.
scan.useLocale(Locale.FRANCE);Además, el siguiente bloque de código en su código hará que el bucle finalice después de leer el primer número como el primer número en su archivo que no es igual a cero. Simplemente elimine estas líneas para obtener el resultado deseado:
if (nextInput != 0) { break; }Opcion 2:
Lea una línea, divídala en un punto y coma, reemplace la coma con un punto, analice cada elemento de la matriz resultante en Double y almacene lo mismo en aList .
Manifestación:
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); } }Producción:
[17.23, 12.1, 20.34, 88.23523] Una alternativa para reemplazar la coma con el punto es usar NumberFormat como se muestra a continuación:
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); } }