Hola, he estado revisando tu código y tus explicaciones y me ha resultado bastante difícil de seguir debido a que es extenso y hablas de muchas cosas. Como recomendación: escribe mensajes donde definas con precisión lo que quieres hacer y el punto concreto donde tienes el problema. Una vez resuelto ese punto concreto, responde introduciendo el siguiente código o siguiente problema. En este caso podrías haber ido tratando primero una forma de recorrer y cuando estuviera comentada y aclarada pasar a la siguiente. Así sería más fácil revisar y encontrar solución a los problemas, ya que al leer todo junto se hace incomprensible o difícil de entender (con lo cual la gente no responderá porque no entiende).
Sobre tu código de ListaOrdenada te digo lo siguiente:
Tratas de hacer algo que parece sencillo pero tiene su complicación, que es la modificación de una colección de elementos al mismo tiempo que la recorres (modificación concurrente).
Normalmente diría que el enfoque que se le suele dar a esto es distinto: digamos que el enfoque más habitual sería añadir lo que quieras añadir a la lista, después ordenarla con el criterio con que quieras ordenarla y ya está.
Pero supongamos que queremos hacer una modificación concurrente.
En el método ordenado For usas una comparación para comprobar si la palabra sería la primera de la lista y en ese caso insertas la palabra la primera de la lista, luego otra comparación para comprobar si la palabra sería la última de la lista y en ese caso insertas la palabra la última de la lista. Por último, otra comparación en caso de que no se cumpla ninguna de las dos condiciones anteriores donde recorres todas las palabras menos la primera y la última, compruebas que la palabra tendría que colocarse entre la actual que recorres y la siguiente. Si es así, insertas la palabra en la posición en que te encuentras (desplazando así las palabras mayores hacia delante en la lista).
Esto está bien pensado, pero un programador con experiencia no estaría muy de acuerdo con este código porque no se ve eficiente. Te voy a indicar por qué para que trates de razonarlo y ver si llegas a las mismas conclusiones:
- Si puedes recorrer toda la lista usando un for, no parece necesario comprobar el primer y último elemento de la lista por separado, ya que podemos hacerlo dentro del for. Esto hace el código más corto y más fácil de entender (cosa valorada en un programador).
Para ello debemos empezar a buscar en el bucle por el 0 en lugar de por el 1 (así incluimos el primer elemento)
Para saber si estamos en el primer o último elemento podemos usar el valor de i. Si es cero es el primer elemento de la lista y hacemos un análisis especial porque no tenemos elemento anterior en la lista.
Si es el último elemento de la lista no tenemos que hacer nada especial porque sí tenemos elemento anterior en la lista.
El código quedaría así:
for(int i=0;i<listaO.size();i++){
if (i==0 && nombre.compareToIgnoreCase(listaO.get(i))<0) {listaO.add(i,nombre); break; }
if (i!=0 && nombre.compareToIgnoreCase(listaO.get(i))<0&&nombre.compareToIgnoreCase(listaO.get(i-1))>=0){
listaO.add(i,nombre); break;
}
if (i==listaO.size()-1 ) { //&& nombre.compareToIgnoreCase(listaO.get(i))>=0
listaO.add(nombre); break;
}
}
Pero algunos programadores no estarían muy conformes con esto por el uso de break; dentro de bucles for se suele considerar poco elegante utilizar break.
Otros programadores dirían que estamos manipulando una colección mientras la recorremos con un bucle for y esto es "no seguro". De hecho si eliminas los break puedes entrar en un bucle infinito, porque al mismo tiempo que recorres la colección la modificas y listaO.size() va cambiando, los índices de los elementos cambian... lo cual se dice que es programación insegura.
El recorrido seguro que permite modificaciones concurrentes se logra mediante iteradores. Pero si usamos un iterador normal, nos permite eliminar elementos a la colección pero no añadirlos.
En cambio un iterador de tipo ListIterator sí nos permite añadir elementos (ver
https://docs.oracle.com/javase/8/docs/api/java/util/ListIterator.html)
Con esto, podríamos usar este código:
public void ordernadoITR(){
ListIterator<String> listaITR=listaO.listIterator();
Scanner teclado=new Scanner(System.in);
System.out.print("Escriba nombre: ");
String nombre=teclado.nextLine();
boolean yaHaSidoInsertado=false;
while(listaITR.hasNext() && yaHaSidoInsertado==false){
if (nombre.compareToIgnoreCase(listaITR.next())<0 && yaHaSidoInsertado==false){
listaITR.previous();
listaITR.add(nombre); //Insertamos
yaHaSidoInsertado=true;
}
}
if (yaHaSidoInsertado == false) { listaO.add(nombre);}//Si no se insertó antes de algún elemento existente lo insertamos al final
System.out.println(listaO);
}
Con esto hemos dejado de usar break (que no suele recomendarse, aunque tampoco es algo prohibido).
Habría más formas de hacerlo y de enfocarlo, espero que lo comentado te sirva de ayuda.
Saludos