texto - manejo de archivos en java netbeans
AgrupaciĆ³n de palabras de un archivo de texto a un Arraylist sobre la base de la longitud (2)
En primer lugar, su código solo funciona para los archivos que contienen una palabra por línea, ya que está procesando líneas enteras como palabras. Para hacer que su código sea más universal, debe procesar cada línea dividiéndola en palabras:
String[] words = strLine.split("//s+")
En segundo lugar, no necesita ninguna estructura de datos temporal. Puede agregar sus palabras al mapa justo después de leer la línea del archivo. arr
listas arr
y lengths
son en realidad inútiles, ya que no contienen ninguna lógica, excepto el almacenamiento temporal. Está utilizando la lista de lengths
solo para almacenar las longitudes que ya se han agregado al mapa hm
. Lo mismo se puede lograr invocando hm.containsKey(s.length())
.
Y un comentario adicional sobre tu código:
for(int x=0;x<lengths.size();x++) {
if(s.length()==lengths.get(x))
already=true;
}
cuando tiene un bucle como este cuando solo necesita encontrar si alguna condición es verdadera para cualquier elemento, no es necesario que continúe el bucle cuando la condición ya se ha encontrado. Debe utilizar una palabra clave break
dentro de su instrucción if para terminar el bloque de bucle, por ejemplo
for(int x=0;x<lengths.size();x++) {
if(s.length()==lengths.get(x))
already=true;
break; // this will terminate the loop after setting the flag to true
}
Pero como ya mencioné, no lo necesita en absoluto. Eso es solo para fines educativos.
public class JavaApplication13 {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
BufferedReader br;
String strLine;
ArrayList<String> arr =new ArrayList<>();
HashMap<Integer,ArrayList<String>> hm = new HashMap<>();
try {
br = new BufferedReader( new FileReader("words.txt"));
while( (strLine = br.readLine()) != null){
arr.add(strLine);
}
} catch (FileNotFoundException e) {
System.err.println("Unable to find the file: fileName");
} catch (IOException e) {
System.err.println("Unable to read the file: fileName");
}
ArrayList<Integer> lengths = new ArrayList<>(); //List to keep lengths information
System.out.println("Total Words: "+arr.size()); //Total waords read from file
int i=0;
while(i<arr.size()) //this loop will itrate our all the words of text file that are now stored in words.txt
{
boolean already=false;
String s = arr.get(i);
//following for loop will check if that length is already in lengths list.
for(int x=0;x<lengths.size();x++)
{
if(s.length()==lengths.get(x))
already=true;
}
//already = true means file is that we have an arrayist of the current string length in our map
if(already==true)
{
hm.get(s.length()).add(s); //adding that string according to its length in hm(hashmap)
}
else
{
hm.put(s.length(),new ArrayList<>()); //create a new element in hm and the adding the new length string
hm.get(s.length()).add(s);
lengths.add(s.length());
}
i++;
}
//Now Print the whole map
for(int q=0;q<hm.size();q++)
{
System.out.println(hm.get(q));
}
}
}
es este enfoque es correcto?
Explicación:
- cargar todas las palabras en una ArrayList.
- luego itere a través de cada índice y verifique la longitud de la palabra agréguelo a un ArrayList de cadenas que contengan esa longitud donde se mapean estas ArrayList en un hashmap con la longitud de las palabras que contiene.
Su enfoque es largo, confuso, difícil de depurar y por lo que veo no es bueno en cuanto a rendimiento (consulte el método contains
). Mira esto:
String[] words = {"a", "ab", "ad", "abc", "af", "b", "dsadsa", "c", "ghh", "po"};
Map<Integer, List<String>> groupByLength =
Arrays.stream(words).collect(Collectors.groupingBy(String::length));
System.out.println(groupByLength);
Esto es solo un ejemplo, pero entiendes el punto. Tengo un conjunto de palabras, y luego uso las secuencias y la magia de Java8
para agruparlas en un mapa por longitud (exactamente lo que estás tratando de hacer). Obtienes la transmisión y luego la recopilas en un mapa, agrupando por la longitud de las palabras, por lo que colocarás cada palabra de 1 letra en una lista debajo de la tecla 1
etc.
Puede usar el mismo enfoque, pero tiene sus palabras en una lista, así que recuerde no utilizar Arrays.stream()
sino solo .stream()
en su lista.