Академический Документы
Профессиональный Документы
Культура Документы
- Arrays (Vectores) 1
TEMARIO DE CURSO
PROGRAMACIÓN JAVA SE
Iñaki Martín
CAPÍTULO 4
rt
ARRAYS (VECTORES) ín
M a
©
ik
a
Temario de curso JavaSE
Iñ
©
© Iñaki Martín
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-SinObraDerivada 4.0 Internacional.
4.- Arrays (Vectores) Arrays: Resumen 2
Array:crear Matriz:recorrer
Iñaki Martín
n
int[] array1 = new int [9] //crea array de 9 in int[][] mat2={{4,1,8,36}{4,1,8,36}};
rt í
int[] array2 = {4,1,8,36} //crea array de 4 int for(int f=0;f< mat2.length; f++){
int[][] mat1 = new int [3][4]; //crea matriz 3x4 for(int c=0;c< mat2[f].length; c++){
a
System.out.print( mat2 [f][c]) ;
}
M
©
ik
Clase_Arrays:Métodos
Array:ordenar(burbuja)
a
Temario de curso JavaSE
Iñ
(nada)
se puede ordenar) // version más simple de todas
Indica si los arrays son int[] datos = {4, 1, 8, 36,0,33,11,43};
array Arrays.equals(arr1,arr2) iguales (contenido y orden) for(int i=0; i<datos.length-1 ; i++){
©
int [] arr1 = new int9]; for(int j=0; j<datos.length-1; j++){
Devuelve una copia de arr1
String Arrays.copyOf(arr1,tam) if (datos[j] > datos[j+1]) {
de tamaño tam int aux = datos[j+1];
Devuelve una copia de arr1 datos[j+1] = datos[j];
String Arrays.copyOfRange(arr1,ini,fin) desde la posición ini datos[j] = aux;
(incluido) hasta fin (excluido) } // version más correcta
Rellena todo el arra arr1 con } boolean huboCambio = true;
int Arrays.fill(arr1,cont) while (huboCambio){
el contenido cont } huboCambio = false;
Devuelve el array arr1 como for(inti=0;i<datos.length-1;i++){
String Arrays.toString(arr1) un String
if(datos[i]>datos[i+1]){
int aux = datos[i];
datos[i] = datos[i+1];
datos[i+1] = aux;
huboCambio = true;
}
}
}
4.- Arrays (Vectores) Array, concepto 3
๏ Para distinguir entre todos esos valores, se le pone un "apellido" al nombre de la variable, que es un número,
ín
de modo que cada número identifica a cada uno de los diferentes valores de la variable.
๏ Una idea más conceptual para entender los arrays es
imaginar al array como un tren, que tiene vagones numerados,
a rt y
M
que dentro de cada vagón, se almacena un contenido.
©
1
ik
12
42
78
38
El array es el tren, los elementos del array son cada uno de los
a
Temario de curso JavaSE
๏ NOTA: En inglés se usa el término array, que se traduce en castellano como Vector (en sudamérica a veces se traduce por “Arreglo”). Nosotros en
este libro optamos por utilizar el término inglés array, no por que nos guste más, sino por ser el más utilizado también en los entornos profesionales.
4.- Arrays (Vectores) Crear un array 4
Creación de un array
๏ Para crear (DECLARAR) un array, hay que seguir la siguiente estructura:
// tipo_del_array [ ] nombre_del_array ;
int [] alfa;
Iñaki Martín
๏ Con esto se declara el array, esto es, se le dice a la memoria: "Memoria, crea sólo el nombre de una variable
ín
que se llama unVector, y que es de tipo array de integer. Pero aun no lo des tamaño”. Mientras no dimensione,
el valor del array es NULL.
rt
a
๏ Así se declara que va a existir un array, pero no se ha construido aún, pues necesita saber cuántos elementos
M
©
va a tener (DIMENSIONAR). Esto es necesario siempre, antes de empezar a dar valores a la variable. Para
ik
decir cuantos valores tiene el array, se puede decir después de declararlo:
a
Temario de curso JavaSE
Iñ
que es como decirle: "Memoria, a la variable que tenias ya declarada (unVector) hazle nuevo (new)
sitio para 3 elementos de tipo int"
©
๏ Ahora ya sí se puede ir dando el valor a cada uno de los elementos del array (ASIGNAR), igual que a cualquier
otra variable. Entre los corchetes, se pone el índice del elemento a tratar (el número del vagón del tren):
alfa[1] = 23;
alfa[2] = 17;
๏ Siguiendo con el ejemplo del tren, el resumen de lo que se ha dicho hasta ahora sería:
alfa -> es el TREN COMPLETO
alfa[2] -> es UN VAGON del tren, y el número 2 es el INDICE del array (el número de vagón)
4.- Arrays (Vectores) Trabajando con arrays (I) 5
๏ Si se desea dar valores a los elementos del array de uno en uno se puede hacer así:
Iñaki Martín
ín
int lasNotas [] = new int [e];
rt
lasNotas[0] = 23;
lasNotas[1] = 145;
a
lasNotas[2] = 6253;
M
©
ik
Cuidado. Los índices del array comienzan numerándose desde 0, así
que el array tiene un tamaño de 5, pero los índices van del 0 al 4
a
Temario de curso JavaSE
Iñ
• Se puede crear el array y a la vez, darle valor a sus elementos, en este caso, no hace falta dimensionarlo,
el array toma el tamaño del número de elementos con los que se inicializa:
int tabla1[] =
int tabla2[] = ©
{31, 62, 73, 43} ;
new int[] {1,2,3};
// una manera de crear y inicializar un array
// otra manera de crear y inicializar un array
• Los elementos de un array se comportan como si fueran una variable normal del tipo elegido.
Esto es, un elemento de un array de int, se comporta como una variable int normal: se puede sumar, asignar…
System.out.println("Valor 0 del array tabla1 es “+tabla1[0]); // imprimir por pantalla
System.out.println(tabla1[2]); // imprimir por pantalla
int numeroElegido = tabla1[2]; // asignar a una variable
int numeroduplicado = tabla1[2] * 2; // operar con el elemento
4.- Arrays (Vectores) Trabajando con arrays (II) 6
๏ Lo más interesante de los arrays es la posibilidad de emplear una variable para indicar el índice del
elemento.
๏ Modificando el valor de dicha variable (por ejemplo, mediante un bucle), podemos ir accediendo a cada
elemento del array, “recorriendo” los valores (los vagones del tren)
๏ Por ejemplo, si deseo imprimir todos los elementos de un array, seguidos, podría hacerse así:
Iñaki Martín
n
String nombres[] = {”Juan”, “Pablo”, “Ana”, “Eva” } ;
rt í
System.out.println(nombres[0]);
System.out.println(nombres[1]);
a
System.out.println(nombres[2]);
System.out.println(nombres[3]);
M
©
ik
๏ Si nos fijamos, es realmente una misma línea que se repite y que es casi igual en todos los casos... esto
a
Temario de curso JavaSE
huele a bucle. En este caso lo que varia es un solo número, y que además, va tomando sucesivamente los
Iñ
valores 0,1,2,3,4…. vamos, lo mismo que ocurre con el índice de un bucle for… Así pues, las 5 líneas
anteriores se podrían haber resumido en :
©
String nombresDelEquipo[] = {”Juan”, “Pablo”, “Ana”, “Eva” } ;
for (int k = 0; k < 4; k++) {
System.out.println(nombres[ k ]);
}
✴ lo que haya dentro del for se repetirá mientras sea cierto que k<4
Por lo tanto, k va a valer, sucesivamente, 0,1,2,3 ….. que son cada uno de los indices que usábamos
para escribir inicialmente el array… al escribir el elemento que tenga ese indice, escribiremos todo el array.
4.- Arrays (Vectores) Trabajando con arrays (III) 7
Detalle paso a paso de la ejecución del bucle anterior String nombres[] = {”Juan”, “Pablo”, “Ana, “Eva” } ;
for (int k = 0; k < 4; k++) {
System.out.println(nombres[ k ]);
1. la variable k se pone inicialmente con valor 0 }
n
System.out.println(nombresDelEquipo[ k ]);
pero como k=0, realmente hace
rt í
a
System.out.println(nombresDelEquipo[ 0 ]);
e imprime "Juan"
M
©
ik
4. el bucle acaba, con lo que se incrementa el valor de k, que pasa a ser 1
5. se entra nuevamente en el bucle, pues la condición se cumple, pues se mira si k<4, y k =1
a
Temario de curso JavaSE
Iñ
6. se ejecuta la línea del System.out..., que intenta hacer
System.out.println(nombresDelEquipo[ k ]);
©
pero como k=1, realmente hace
System.out.println(nombresDelEquipo[ 1 ]);
imprime " Pablo "
7. el bucle acaba, con lo que se incrementa el valor de k, que pasa a ser 2
8. …. y todo se repite nuevamente,
y se van imprimiendo los nombres de todos los elementos del array, con solo una línea,
¿cuando acaba el bucle? cuando no se cumpla k<4, que ocurrirá por vez primera cuando k=4,
así que k habrá valido desde 0 hasta 3, que son realmente todos los elementos del array
4.- Arrays (Vectores) Arrays: características 8
๏Los arrays son estructuras estáticas, no se puede modificar el tamaño. Si no sabemos a priori el
tamaño que vamos a necesitar, no debemos usar arrays, sino colecciones, que se verán más adelante
๏En la declaración de un array, los corchetes pueden ir delante o detrás del nombre del array.
Iñaki Martín
n
int[] arraydepruebas = new int [5];
í
hacen lo mismo (SOLO vale en la declaración)
rt
int arraydepruebas [] = new int [5];
M a
©
๏Un array de tipo int no es una variable de tipo int. Los elementos de un array int sí son variables de
tipo int
ik
a
Temario de curso JavaSE
Iñ
int[] arraydepruebas = new int [5];
arraydepruebas [0] = 5; // un elemento de un array int, es como un int
arraydepruebas = 5; // ERROR: arraydeprueba es EL ARRAY entero, el tren, no un int
©
๏ Respecto al contenido de un array, desde el momento en que el array se dimensiona todos los
elementos del array son inicializados directamente con los valores por defecto de cada tipo de
dato (el valor por defecto es 0 para los tipos de número, false para boolean y ‘\0000’ para char)
No importa sin la variable es de clase (global) o de método (local) o de bloque o de lo que sea. A un array, según se dimensiona, se le da valor
inicial siempre a todo su contenido.
4.- Arrays (Vectores) Arrays: atributos y métodos 9
rt ín
DEVUELVE ATRIBUTO DESCRIPCION
M a
©
int .length operación que da como resultado el tamaño (número de elementos) del array.
ik
a
int arraydepruebas [] = new int [5];
Temario de curso JavaSE
Iñ
©
DEVUELVE METODO DESCRIPCION
otro array .clone() Crea una copia de un array:
int [ ] copiaDeNotas = notas.clone();
Ejemplo de arrays
๏ El uso de los arrays dentro de bucles es una de las características más potentes de cualquier lenguaje de
programación. Veamos algunos un par de ejercicios de ejemplo:
1. Enunciado: Si se tienen dos arrays, de alumnos y sus notas, mostrar por pantalla el nombre y la nota de cada alumno, y
emitir un mensaje si el alumno ha suspendido. Al final, informar de cual ha sido la media de las notas de la clase:
Iñaki Martín
ín
String alumnos[] = {"Jose", "Pablo", "Ernesto", "David", "Luis"};
rt
int notas [] = { 5, 6, 3, 2, 8};
int sumaNotas = 0;
a
for (int i = 0; i < alumnos.length; i++) {
System.out.println("El alumno "+ alumnos[i]+" tiene de nota un "+notas[i]);
M
if (notas[i] < 5 ){
©
ik
}
sumaNotas = sumaNotas + notas[i];
a
}
Temario de curso JavaSE
Iñ
System.out.println("/n La nota media de la clase es de "+ notaMedia );
©
2. Enunciado: Dado un array int[] arrayDeDatos = {8,2,5,4,9,1,0,8,9,3} construir un programa que copie el arrayDeDatos en el
array llamado copiaDeDatos, pero sumando 2 a cada elemento, y que escriba el array copiaDeDatos por pantalla, esto es,
que salga :
int[] arrayDeDatos = {8,2,5,4,9,1,0,8,9,3};
"el elemento 1 de copiadedatos es 10” int[] copiaDeDatos = new int[arrayDeDatos.length];
"el elemento 2 de copiadedatos es 4"
for (int i = 0; i < arrayDeDatos.length; i++) {
"el elemento 3 de copiadedatos es 7" copiaDeDatos[i] = arrayDeDatos[i] + 2;
"el elemento 4 de copiadedatos es 6" }
split()
๏ El método split() no se usa con arrays, sino con la clase String, pero permite crear un “array de cadenas”,
utilizando el parámetro que se le pasa como elemento “troceador” de la cadena original.
๏ Ejemplo: si se tiene una cadena con varios nombres separados por comas, se puede crear un array con todos los
nombres, usando el modo split() y diciendo que trocee la cadena cada vez que se encuentre una coma.
Iñaki Martín
cad[0] es “Juan"
n
String cad = "Juan,Pedro,Luis,Pablo";
í
cad[1] es “Pedro”
rt
String [ ] nombres = cad.split(“,”);
cad[2] es “Luis”
cad[3]
creares “Pablo"
a
๏ Igualmente, en este otro ejemplo puedo usar como separador un espacio en blanco para un array de cadenas
que contenga cada una de las palabras de una frase :
M
©
ik
String frase = "En un lugar de la Mancha";
a
Temario de curso JavaSE
Iñ
Cuidado: split() usa como parámetro no un String, sino una expresión regular. Aun no se ha visto que son
©
expresiones regulares, pero sólo como aviso, por ahora, NO se puede usar como separador en split()
directamente un punto (“.”) ni asterisco (“*”). Algunos ejemplos más complejos son :
cadena.split(“\\.”); // para usar un punto como separador
cadena.split(“”); // si no se usa separador, se separa la cadena carácter a carácter
Para otros modelos de separadores en los elementos, acudir al final a los temas avanzados o al tema de Expresiones Regulares
StringTokenizer
๏ Similares efectos al método split() se puede conseguir usando la clase StringTokenizer.
Sin embargo, y citando expresamente a la API de Oracle, “StringTokenizer es una clase heredada de versiones
antiguas, que se conserva por razones de compatibilidad, aunque su uso en código nuevo está desaconsejado”
4.- Arrays (Vectores) Arrays multidimensionales (I) 12
Arrays multidimensionales
๏ Los arrays unidimesionales que se han visto hasta ahora se les suele llamar “arrays” (incluso a veces,
“listas”) y usaban un solo índice para acceder a cada elemento.
๏ Pero un array en Java puede tener más de una “dimensión”, y definirse por lo tanto con más de un índice.
Los arrays bidimensionales (de dos dimensiones) suelen ser llamados “matrices” o “tablas”
Iñaki Martín
ín
๏ Una matriz necesita dos índices para acceder a sus elementos. Gráficamente podemos representar una
rt
matriz como una tabla de n filas y m columnas cuyos elementos son todos del mismo tipo.
a
Este gráfico indica las “posiciones” de los índices de cada uno de los elementos de una matriz de 4x3
M
©
ik
Columna 0 Columna 1 Columna 2
Fila 0
a
Matriz [0] [0] Matriz [0] [1] Matriz [0] [2]
Temario de curso JavaSE
Iñ
Fila 1 Matriz [1] [0] Matriz [1] [1] Matriz [1] [2]
Fila 2 Matriz [2] [0] Matriz [2] [1] Matriz [2] [2]
©
Fila 3 Matriz [3] [0] Matriz [3] [1] Matriz [3] [2]
๏ Un elemento de una matriz es localizado mediante las coordenadas representadas por su número de fila (el
primer índice usado) y número de columna (el segundo índice usado)
๏ Cada “casilla” de la matriz es un elemento de la matriz, y almacena un valor. El tipo del valor almacenado es
el tipo del que se haya declarado la matriz.
4.- Arrays (Vectores) Arrays multidimensionales (II) 13
๏ Para declarar un array multidimensional, se hace igual que con uno de una sola dimensión, pero añadiendo
otros corchetes para la segunda dimensión
Ejemplos de declaración de matrices:
Iñaki Martín
// <tipoDato> <nombreArray> [ ] [ ];
char puntos[ ][ ];
int plazas [ ][ ];
rt ín
a
double [ ][ ] unaMatriz;
M
©
๏ El tipo de dato será el mismo para todos los elementos del array (sea uni o multidimensional)
ik
๏ Al igual que ocurría con los arrays variables, una declaraciones no crea realmente una matriz, es necesario
a
Temario de curso JavaSE
Iñ
puntos = new char[8][12]; // matriz con 8 filas y 12 columnas
©
plazas = new int[10][5]; // matriz de 10 filas por 5 columnas
๏ También se puede dar valor inicial a los elementos a la vez que se declara la matriz:
int tabla1[][] = { {31, 62, 73, 43} , {23, 44, 65, 19} };
๏ En este caso el número de filas y columna no se indica expresamente, se da con el número de elementos. El
ejemplo anterior crea una matriz de 2x4 (dos filas y cuatro columnas)
4.- Arrays (Vectores) Arrays multidimensionales (III) 14
n
๏ Al crear una matriz, solo es obligatorio indicar el número de filas.Otro ejemplo:
int [][] m = new int[3][];
rt í
crea una matriz m de 3 filas.
M a
©
ik
๏ A cada fila se le puede definir luego un número distinto de columnas:
m[0] = new int[3];
a
Temario de curso JavaSE
Iñ
m[2] = new int[2];
Temas avanzados ©
Asignaciones con arrays multidimensión
• Cuando se asigna una referencia de un array a otro array, ambas referencias han de tener la misma dimensión (la misma
dimensión, no el mismo número de elementos por dimensión)
int [ ] puntos;
int [ ][ ] matrizpuntos = new int [3][ ];
puntos = matrizpuntos; // ERROR, matrizpuntos es de dos dimensiones
int[ ] motas = new int [6];
puntos = motas ; // ok, motas es de una dimension
matrizpuntos[0] = motas ; // ok, matrizpuntos[0] es de una dimension
4.- Arrays (Vectores) Arrays multidimensionales (IV) 15
๏ Un array bidimensional es realmente un array de arrays; es decir, se puede ver como un array unidimensional,
donde cada elemento no es un tipo normal (int, double), sino otro array.
๏ Por ello NO es obligatorio que cada fila de la matriz tenga el mismo tamaño.
Por ejemplo, podemos declarar e inicializar la siguiente matriz bidimensional
int [ ][ ] matriz={{1,2,3,4,5},{5,6},{7,8,9,10,11,12},{13}};
// La primer fila tiene cinco elementos {1,2,3,4,5}
Iñaki Martín
ín
// La tercera fila tiene seis elementos {7,8,9,10,11,12}
rt
// La cuarta fila tiene un elemento {13}
a
Cuidado al leer arrays irregulares con un for, pues se ha de saber qué tamaño tiene cada dimensión….
M
Tamaño de una matriz
©
ik
๏ ¿Cómo saber el tamaño de cada dimensión en el caso de arrays bidimensionales?
a
Temario de curso JavaSE
©
Como una matriz es un array de arrays, el tamaño del array es realmente el número de filas de la matriz
Como una matriz es un array de arrays, matriz[0] representa a la primera fila de la matriz, matriz[1] es la segunda fila, etc
El tamaño de cada una de las filas es, por lo tanto, el número de columnas de la matriz, considerando siempre que se trate de una matriz de dos
dimensiones, y regular, esto es, en la que todas las filas tienen el mismo número de elementos). Si se trabaja con matrices irregulares, el
tamaño de cada fila de la matriz se indica con la misma instrucción, matriz [0].length; solo que cambiando el 0 por el número de cada fila, en
cada caso.
int[][] mimatriz = new int[2][6];
int numeroDeFilas = unarrayirregular.length;
int numeroDeComlumnas = unarrayirregular[0].length;
4.- Arrays (Vectores) Recorrer una matriz 16
๏ Para acceder a los elementos de una matriz se indican los índices de las dos dimensiones:
rt ín
Un bucle va a recorrer cada fila de la matriz, y dentro de este (para cada fila), hay otro bucle que hace
referencia a cada columna de dicha fila:
M a
©
ik
Int numFilas = 4, numCols = 4;
boolean plaza [] [] = new boolean [numFilas] [numCols];
a
Temario de curso JavaSE
for (int fila = 0; fila < numFilas; fila++){ // Bucle de las filas
Iñ
for (int col = 0; col < numCols; col++){ // Bucle de las columnas
plaza [fila] [col] = true;
}
}
© [0] [0]
[1] [0]
[2] [0]
[0] [1]
[1] [1]
[2] [1]
[0] [2]
[1] [2]
[2] [2]
[0] [3]
[1] [3]
[2] [3]
[3] [0] [3] [1] [3] [2] [3] [3]
4.- Arrays (Vectores) Clase Arrays 17
Clase Arrays
๏ Java ofrece la clase Arrays, que dispone de varios métodos estáticos (ya se explicará qué significa esto) que
permiten trabajar con el array de forma completa (no con sus elementos si con el array como conjunto)
๏ Son muy útiles pues nos facilitan acciones que de otro modo habría que programar
๏ Algunos de los métodos más interesantes son; EJEMPLO PARA TODOS LOS METODOS
Iñaki Martín
rt ín
Ordena arr1 (si el contenido se puede ordenar)
a
Arrays.sort(arr1);
M
©
ik
Arrays boolean Arrays.equals(arr1,arr2) Indica si los arrays son iguales (contenido y orden)
int []x = {4,1,72,37,5,2,55,24};
a
Temario de curso JavaSE
Iñ
Arrays array Arrays.copyOf(arr1,tam) Devuelve una copia de arr1 de tamaño tam. La copia no es deep, sino shallow
©
int []x = Arrays.copyOf(arr1,4);
Arrays array Arrays.copyOfRange(arr1,ini,fin) Devuelve una copia de arr1 desde la posición ini (incluido) hasta fin (excluido)
int []x = Arrays.copyOfRange(arr1,2,4);
Arrays array Arrays.fill(arr1,cont) Rellena todo el array arr1 con el contenido cont
int []x = Arrays.fill(arr1,0);
Normalmente existen métodos sobrecargados para permitir usar en los parámetros todo tipo de datos primitivos
4.- Arrays (Vectores) Ordenar por burbuja
Ordenación 18
n
‣ En el bucle interior, se va ir comparando cada elemento del array (desde la posición 0 al final) con el siguiente, y se
intercambiarán si es necesario, para dejar el mayor siempre a la derecha del otro. De este modo, vamos con
sucesivos intercambios “adelantando” en el array los valores menores, y “atrasando” los mayores.
rt í
M a
‣ Con cada vuelta interna se asegura además que el valor que se ha cogido “avanza” hacia la derecha todo lo que
puede. De hecho, tras el primer bucle interno, el valor que queda al “final” del array ha de ser seguro el mayor de
©
ik
todos los valores del array.
‣ Las sucesivas vueltas exteriores tan solo aseguran que se coloque al final el segundo-mayor, el tercer-mayor, etc.
a
Temario de curso JavaSE
‣ El problema es que cuando ya ha ordenado parte del array vuelve a compararlo cuando no es necesario, por lo que no
Iñ
es muy eficiente. i=
i=
i=
0
0
0
j
j
j
=
=
=
0:
1:
2:
25
25
25
64
13
13
13
64
24
24
24
64
18
18
18
11
11
11
43
43
43
i= 0 j = 3: 25 13 24 18 64 11 43
©
int[] nums = {64, 25, 13, 24, 18, 11, 43}; i=
i=
0
0
j
j
=
=
4:
5:
25
25
13
13
24
24
18
18
11
11
64
43
43
64
int aux; i= 1 j = 0: 13 25 24 18 11 43 64 Se marcan en
i= 1 j = 1: 13 24 25 18 11 43 64
for (int i = 0; i < nums.length - 1; i++) { i= 1 j = 2: 13 24 18 25 11 43 64 color los
for (int j = 0; j < nums.length - 1; j++) { Así se ordena i=
i=
1
1
j
j
=
=
3:
4:
13
13
24
24
18
18
11
11
25
25
43
43
64
64 intercambios
if (nums[j] > nums[j + 1]) { ascendentemente, para i=
i=
1
2
j
j
=
=
5:
0:
13
13
24
24
18
18
11
11
25
25
43
43
64
64 efectivos que
aux = nums[j]; ordenar i=
i=
2
2
j
j
=
=
1:
2:
13
13
18
18
24
11
11
24
25
25
43
43
64
64 se han hecho
nums[j] = nums[j + 1]; descendentemente i=
i=
2
2
j
j
=
=
3:
4:
13
13
18
18
11
11
24
24
25
25
43
43
64
64 en cada una
nums[j + 1] = aux; cambiar en el if el sentido i=
i=
2
3
j
j
=
=
5:
0:
13
13
18
18
11
11
24
24
25
25
43
43
64
64 de las vueltas
} de la comparación, i=
i=
3
3
j
j
=
=
1:
2:
13
13
11
11
18
18
24
24
25
25
43
43
64
64 del array
} cambiar el > por un < i= 3 j = 3: 13 11 18 24 25 43 64
} i= 3 j = 4: 13 11 18 24 25 43 64 interno.
i= 3 j = 5: 13 11 18 24 25 43 64
System.out.print("\nArray Ordenado: "); i= 4 j = 0: 11 13 18 24 25 43 64 Vemos que las
i= 4 j = 1: 11 13 18 24 25 43 64
for (int i = 0; i < nums.length; i++) { i= 4 j = 2: 11 13 18 24 25 43 64 últimas vueltas
i= 4 j = 3: 11 13 18 24 25 43 64
System.out.print(nums[i] + " "); i= 4 j = 4: 11 13 18 24 25 43 64 han sido
i= 4 j = 5: 11 13 18 24 25 43 64
} i= 5 j = 0: 11 13 18 24 25 43 64 innecesarias…
i= 5 j = 1: 11 13 18 24 25 43 64
i= 5 j = 2: 11 13 18 24 25 43 64
Más allá de que la burbuja no sea el mejor método de ordenación de arrays, el propio algoritmo tiene a su vez muchas i=
i=
5
5
j
j
=
=
3:
4:
11
11
13
13
18
18
24
24
25
25
43
43
64
64
variantes. La que hemos indicado es la más facil de recordar, pero aun dentro de las versiones de la burbuja, la menos eficiente. i= 5 j = 5: 11 13 18 24 25 43 64
4.- Arrays (Vectores) Ordenación por burbuja (avanzado) 19
• Como ya se ha dicho, el propio algoritmo de la burbuja tiene a su vez muchas variantes. La que hemos indicado anteriormente es la más facil de
recordar, pero aun dentro de las versiones de la burbuja, la menos eficiente.
• Una versión más eficiente del anterior es cambiar la condición de fin del bucle interior, y poner nums.length - 1 - i en vez de nums.length - 1
i= 0 j = 0: 25 64 13 24 18 11 43
int[] nums = {64, 25, 13, 24, 18, 11, 43};
Iñaki Martín
i= 0 j = 1: 25 13 64 24 18 11 43
int aux; i= 0 j = 2: 25 13 24 64 18 11 43
n
for (int i = 0; i < nums.length - 1; i++) { i= 0 j = 3: 25 13 24 18 64 11 43
í
for (int j = 0; j < nums.length - 1 - i; j++) { i= 0 j = 4: 25 13 24 18 11 64 43
rt
i= 0 j = 5: 25 13 24 18 11 43 64
if (nums[j] > nums[j + 1]) { i= 1 j = 0: 13 25 24 18 11 43 64
aux = nums[j]; i= 1 j = 1: 13 24 25 18 11 43 64
nums[j] = nums[j + 1]; i= 1 j = 2: 13 24 18 25 11 43 64
Se marcan en color los
a
i= 1 j = 3: 13 24 18 11 25 43 64
nums[j + 1] = aux;
}
i=
i=
1
2
j
j
=
=
4:
0:
13
13
24
24
18
18
11
11
25
25
43
43
64
64
intercambios efectivos que se
} i= 2 j = 1: 13 18 24 11 25 43 64
han hecho
M
} i= 2 j = 2: 13 18 11 24 25 43 64
©
i= 2 j = 3: 13 18 11 24 25 43 64
ik
System.out.print("\nArray Ordenado: "); i= 3 j = 0: 13 18 11 24 25 43 64
for (int i = 0; i < nums.length; i++) { i= 3 j = 1: 13 11 18 24 25 43 64
System.out.print(nums[i] + " "); i= 3 j = 2: 13 11 18 24 25 43 64
i= 4 j = 0: 11 13 18 24 25 43 64
}
a
Temario de curso JavaSE
i= 4 j = 1: 11 13 18 24 25 43 64
i= 5 j = 0: 11 13 18 24 25 43 64
Iñ
• Otra versión diferente del método de la burbuja es la siguiente, en la que cada elemento del array se compara con todos los demás,
desplazándose según sea mayor hacia el final, intercambiando igualmente posiciones.
• En este caso, tras el primer bucle interno, el valor que queda al “principio” del array ha de ser seguro el menor de todos los valores del array, y las
©
sucesivas vueltas aseguran que se coloquen seguidamente en cada vuelta el segundo-menor, el tercer-menor, etc.
int[] nums2 = { 64, 25, 13, 24, 18, 11, 43 }; i= 0 j = 1: 25 64 13 24 18 11 43
i= 0 j = 2: 13 64 25 24 18 11 43
int aux2; i= 0 j = 3: 13 64 25 24 18 11 43
for (int i = 0; i < nums2.length; i++) { i= 0 j = 4: 13 64 25 24 18 11 43
i= 0 j = 5: 11 64 25 24 18 13 43
for (int j = i + 1; j < nums2.length; j++) { i= 0 j = 6: 11 64 25 24 18 13 43
if (nums2[j] < nums2[i]) { i= 1 j = 2: 11 25 64 24 18 13 43
i= 1 j = 3: 11 24 64 25 18 13 43
aux2 = nums2[j]; i= 1 j = 4: 11 18 64 25 24 13 43
nums2[j] = nums2[i]; i= 1 j = 5: 11 13 64 25 24 18 43 Se marcan en color los
nums2[i] = aux2; i= 1 j = 6: 11 13 64 25 24 18 43
intercambios efectivos que se
i= 2 j = 3: 11 13 25 64 24 18 43
} i= 2 j = 4: 11 13 24 64 25 18 43
} i= 2 j = 5: 11 13 18 64 25 24 43 han hecho
i= 2 j = 6: 11 13 18 64 25 24 43
} i= 3 j = 4: 11 13 18 25 64 24 43
System.out.print ("\nArray Ordenado: "); i= 3 j = 5: 11 13 18 24 64 25 43
i= 3 j = 6: 11 13 18 24 64 25 43
for (int i = 0; i < nums2.length; i++) i= 4 j = 5: 11 13 18 24 25 64 43
System.out.print (nums2[i] + " "); i= 4 j = 6: 11 13 18 24 25 64 43
i= 5 j = 6: 11 13 18 24 25 43 64
4.- Arrays (Vectores) Ordenación por burbuja (eficiente) 20
• Probablemente la versión más eficiente de todas para el método de la burbuja sea esta, donde se usa una variable boolean (una bandera) para
evaluar si hay algún cambio en las rotaciones, y si no lo hay, no seguir y dar por acabada la ordenación
• Se ahorran así vueltas del bucle innecesarias (ver en el ejemplo de la primera versión, en la impresión de la ejecución, que en las últimas 12
“vueltas” no se realiza cambio alguno, pues el array ya se encuentra ordenado)
Iñaki Martín
n
• Este es un ejemplo de esta versión con flag de “acabado”
rt í
a
int[] nums = { 64, 25, 13, 24, 18, 11, 43 };
boolean huboCambio = true;
int temp;
M
©
while (flag)
ik
{
huboCambio = false;
for (int i = 0; i < nums.length - 1; i++)
a
Temario de curso JavaSE
Iñ
if (nums[i] > nums[i + 1])
{
temp = nums[i];
nums[i] = nums[i + 1];
©
nums[i + 1] = temp;
huboCambio = true;
}
}
}
int n = mat.length;
n
int m = mat[0].length;
rt í
int t;
a
for( int j=0;j< m; j++){
for(int x=0; x < n; x++){
M
for(int y=0; y <m; y++){
©
ik
if(mat[i][j] < mat[x][y]){
t = mat[i][j];
mat[i][j] = mat[x][y];
a
Temario de curso JavaSE
mat[x][y] = t;
}
Iñ
}
}
}
©
}
• Los arrays son objetos, y por lo tanto, la variable del array es una referencia, que contiene elementos, que pueden ser de diferente tipo y valor.
Por ello mismo, una copia de arrays puede ser más complicada de lo imaginado. Si tengo
int [] array1 = new int [2]; array1 [0] = 12; Al cambiar el array2, se ha cambiado también el array1 !!
int [] array2 = array1; array2 [0] = 34
Iñaki Martín
• Lo que se ha hecho es lo que se llama una shallow copy, una copia superficial.
ín
• Lo contrario es hacer una copia que realmente sea distinta del original, lo que se llama una copia profunda (deep copy). Para ello debemos:
rt
- Crear un nuevo array vacío
a
- Copiar los elementos uno a uno ( por ejemplo con un bucle)
Pero nuevamente cuidado al copiar los elementos, no estemos haciendo shallow copy de ellos mismos!!. Este ejemplo:
M
©
ik
Coche [] arrayCoches = new Coche [2];
Coche [] arrayCopia = new Coche [arrayCoches.length];
for (int i = 0; i < arrayCoches.length; i++){
arrayCopia[i] = arrayCoches[i];
a
Temario de curso JavaSE
};
Iñ
hace una copia del array y efectivamente, arrayCoches y arrayCopia tienen diferentes referencias (direcciones de memoria); pero no asi los
Coches que contiene, que hemos copiado con una simple asignación !!.
©
Un cambio en arrayCoches no afecta a arrayCopia (quitar o añadir elementos -Coches-) pero un cambio en cualquier Coche almacenado en el
arrayCoches sí afecta al mismo coche almacenado en arrayCopia.
Lo que hay que hacer, pues, es copiar también los elementos cuidando que esta copia sea realmente deep copy (usando para copiar los elementos
un constructor copia, por ejemplo)
Java ofrece dos métodos más para realizar copias de arrays, pero ambos crean realmente shallow copy, así que cuidado al usarlos:
• Arrays.copyOf(arr1, longitud) - devuelve un array copia de arr1, y longitud es el tamaño de nuevo array, que puede ser diferente del original
(si es mayor, rellena con ceros o null si son objetos) :
int [] array2 = Arrays.copyOf( array1, 2);
• System.arraycopy(varVector1, pos1, varVector2, pos2, longitud2) array1 es el array que vamos a copiar, 1 es la posición inicial desde
donde vamos a copiar, array2 es el array destino de la copia, 0 es su posición inicial y 2 el número de elementos a copiar:
int [] array2 = new int [2]; System.arraycopy( array1, 1, array2, 0 , 2) ;
4.- Arrays (Vectores) Casting de arrays y ejemplos de split 23
n
ss = aa; // ERROR no se puede casting implicito de short a int
rt í
ss = (int) aa; // ERROR tampoco no se puede casting explicito de short a int
aa[0] = ss[0]; // ok, sin problema, se hace casting implicito
a
Considerar que el ultimo casting es de short a int, mientras que en los casos anteriores , se intentaba hacer un casting de un array_de_short a un
array_de_int, que no es lo mismo.
M
©
ik
a
Temario de curso JavaSE
Temas avanzados
Iñ
Otros ejemplos de split() con expresiones regulares avanzadas
©
// Se puede usar split() para trocear un string caracter a caracter (aunque se sigue devolviendo String[] )
String [ ] arra1 = “linea tonta”.split(“”);
// arra1 es {“l”,”i”,”n”,”e”,”a”,” ”,”t”,”o”,”n”,”t”,”a”}
// Se puede hacer que los separadores se incluyan en los elementos, por delante de cada uno que le toque
String [ ] arra2 = “Juan-Pedro-Luis”.split(“(?=-)”);
// arra1 es {“Juan”,”-Pedro”,”,-Luis”}
// Igual que antes, pero con el separador pore detras de los elementos que le toque
String [ ] arr3 = “Juan,Pedro,Luis".split(“(?<=-)”);
// arra1 es {“Juan”,”Pedro-”,”Luis-”}
4.- Arrays (Vectores) split() en versiones Java anteriores a 8 24
• Si se ejecuta un split sin indicar una expresión regular, se divide el string en todos y cada uno de los caracteres de la cadena
• Ejemplo:
String s = "qwerty";
String [ ] sol = s.split(""); // - RESULTADO:
// 6
Iñaki Martín
System.out.println(sol.length);
for (int i = 0; i < sol.length; i++) {
n
// .q..w..e..r..t..y.
í
System.out.print("."+sol[i]+".");
rt
}
a
• Sin embargo, antes de Java8, esta misma ejecución daba como resultado un valor más, vacío, al principio del array
M
©
ik
// - RESULTADO:
// 7
// ...q..w..e..r..t..y.
a
Temario de curso JavaSE
Iñ
• Se debe tener cuidado por tanto si se desea realizar una aplicación que mantenga la compatibilidad con Java/ usando split
©
con cadenas sin usar una expresión regular
• Eso si, en cualquiera de las versiones (Java 7 o superiores) un split sin expresión regular, aplicado a una cadena vacía, da
como respuesta un array con un elemento, un elemento vacío
String s = "";
String [ ] sol = s.split(""); // - RESULTADO:
System.out.println(sol.length); // 1
for (int i = 0; i < sol.length; i++) { // ..
System.out.print("."+sol[i]+".");
}