Categorías
Array Basics

Comience desde length & length () en Java


En primer lugar, ¿puede responder rápidamente a la siguiente pregunta?

Sin el código de autocompletado de ningún IDE, ¿cómo obtener la longitud de una matriz? ¿Y cómo obtener la longitud de una cadena?

Hice esta pregunta a desarrolladores de diferentes niveles: básico e intermedio. No pueden responder la pregunta correctamente o con seguridad. Si bien IDE proporciona un conveniente autocompletado de código, también trae el problema de la «comprensión superficial». En esta publicación, explicaré algunos conceptos clave sobre las matrices de Java.

La respuesta:

int[] arr = new int[3];
System.out.println(arr.length);//length for array
 
String str = "abc";
System.out.println(str.length());//length() for string

La pregunta es ¿por qué la matriz tiene el campo de longitud pero la cadena no? ¿O por qué la cadena tiene el método length () mientras que la matriz no?

Q1. ¿Por qué las matrices tienen la propiedad de longitud?

En primer lugar, una matriz es un objeto contenedor que contiene un número fijo de valores de un solo tipo. Después de que se crea una matriz, su longitud nunca cambia[1]. La longitud de la matriz está disponible como longitud variable de instancia final. Por lo tanto, la longitud se puede considerar como un atributo definitorio de una matriz.

Una matriz se puede crear mediante dos métodos: 1) una expresión de creación de matriz y 2) un inicializador de matriz. Cuando se crea, se especifica el tamaño.

En el ejemplo anterior se usa una expresión de creación de matriz. Especifica el tipo de elemento, el número de niveles de matrices anidadas y la longitud de la matriz para al menos uno de los niveles de anidación.

Esta declaración también es legal, ya que especifica uno de los niveles de anidamiento.

int[][] arr = new int[3][];

Un inicializador de matriz crea una matriz y proporciona valores iniciales para todos sus componentes. Está escrito como una lista de expresiones separadas por comas, entre llaves {y}.

Por ejemplo,

int[] arr = {1,2,3};

Q2. ¿Por qué no hay una clase «Array» definida de manera similar como «String»?

Dado que una matriz es un objeto, el siguiente código es legal.

Object obj = new int[10];

Una matriz contiene todos los miembros heredados de la clase Object (excepto el clon). ¿Por qué no hay una definición de clase de una matriz? No podemos encontrar un archivo Array.java. Una explicación aproximada es que están ocultos para nosotros. Puede pensar en la pregunta: si HAY una clase Array, ¿cómo se vería? Todavía necesitaría una matriz para contener los datos de la matriz, ¿verdad? Por lo tanto, no es una buena idea definir tal clase.

De hecho, podemos obtener la clase de una matriz usando el siguiente código:

int[] arr = new int[3];
System.out.println(arr.getClass());

Producción:

clase [I

«class [I» stands for the run-time type signature for the class object «array with component type int».

Q3. Why String has length() method?

The backup data structure of a String is a char array. There is no need to define a field that is not necessary for every application. Unlike C, an Array of characters is not a String in Java.

References:

[1] Matrices
[2] Matriz JLS

Categorías
Array Java

¿Cómo verificar si una matriz contiene un valor en Java de manera eficiente?

¿Cómo comprobar si una matriz (sin clasificar) contiene un valor determinado? Esta es una operación muy útil y de uso frecuente en Java. También es una de las preguntas más votadas en Stack Overflow. Como se muestra en las respuestas más votadas, esto se puede hacer de varias maneras diferentes, pero la complejidad del tiempo podría ser muy diferente. A continuación, mostraré el costo de tiempo de cada método.

1. Cuatro formas diferentes de comprobar si una matriz contiene un valor

1) Utilizando List:

public static boolean useList(String[] arr, String targetValue) {
	return Arrays.asList(arr).contains(targetValue);
}

2) Utilizando Set:

public static boolean useSet(String[] arr, String targetValue) {
	Set<String> set = new HashSet<String>(Arrays.asList(arr));
	return set.contains(targetValue);
}

3) Usando un bucle simple:

public static boolean useLoop(String[] arr, String targetValue) {
	for(String s: arr){
		if(s.equals(targetValue))
			return true;
	}
	return false;
}

4) Utilizando Arrays.binarySearch():
binarySearch() SOLO se puede utilizar en matrices ordenadas. Si la matriz está ordenada, puede usar el siguiente código para buscar el elemento de destino:

public static boolean useArraysBinarySearch(String[] arr, String targetValue) {	
	int a =  Arrays.binarySearch(arr, targetValue);
	if(a > 0)
		return true;
	else
		return false;
}

2. Complejidad del tiempo

El costo de tiempo aproximado se puede medir usando el siguiente código. La idea básica es buscar una matriz de tamaño 5, 1k, 10k. Puede que el enfoque no sea preciso, pero la idea es clara y simple.

public static void main(String[] args) {
	String[] arr = new String[] {  "CD",  "BC", "EF", "DE", "AB"};
 
	//use list
	long startTime = System.nanoTime();
	for (int i = 0; i < 100000; i++) {
		useList(arr, "A");
	}
	long endTime = System.nanoTime();
	long duration = endTime - startTime;
	System.out.println("useList:  " + duration / 1000000);
 
	//use set
	startTime = System.nanoTime();
	for (int i = 0; i < 100000; i++) {
		useSet(arr, "A");
	}
	endTime = System.nanoTime();
	duration = endTime - startTime;
	System.out.println("useSet:  " + duration / 1000000);
 
	//use loop
	startTime = System.nanoTime();
	for (int i = 0; i < 100000; i++) {
		useLoop(arr, "A");
	}
	endTime = System.nanoTime();
	duration = endTime - startTime;
	System.out.println("useLoop:  " + duration / 1000000);
}

Resultado:

useList:  13
useSet:  72
useLoop:  5

Utilice una matriz más grande (1k):

String[] arr = new String[1000];
 
Random s = new Random();
for(int i=0; i< 1000; i++){
	arr[i] = String.valueOf(s.nextInt());
}

Resultado:

useList:  112
useSet:  2055
useLoop:  99
useArrayBinary:  12

Utilice una matriz más grande (10k):

String[] arr = new String[10000];
 
Random s = new Random();
for(int i=0; i< 10000; i++){
	arr[i] = String.valueOf(s.nextInt());
}

Resultado:

useList:  1590
useSet:  23819
useLoop:  1526
useArrayBinary:  12

Claramente, usar un método de bucle simple es más eficiente que usar cualquier colección. Muchos desarrolladores utilizan el primer método, pero es ineficaz. Enviar la matriz a otra colección requiere recorrer todos los elementos para leerlos antes de hacer algo con el tipo de colección.

La matriz debe estar ordenada, si Arrays.binarySearch() se utiliza el método. En este caso, la matriz no está ordenada, por lo tanto, no debe usarse.

En realidad, si necesita verificar si un valor está contenido en alguna matriz / colección de manera eficiente, una lista o árbol ordenado puede hacerlo en O(log(n)) o hashset puede hacerlo en O(1).

Categorías
Array Java

System.arraycopy () frente a Arrays.copyOf () en Java

Si queremos copiar una matriz, podemos usar System.arraycopy() o Arrays.copyOf(). En esta publicación, utilizo un ejemplo simple para demostrar la diferencia entre los dos.

1. Ejemplos de código simple

System.arraycopy ()

int[] arr = {1,2,3,4,5};
 
int[] copied = new int[10];
System.arraycopy(arr, 0, copied, 1, 5);//5 is the length to copy
 
System.out.println(Arrays.toString(copied));

Producción:

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 1, 2, 3, 4, 5, 0, 0, 0, 0]

Arrays.copyOf ()

int[] copied = Arrays.copyOf(arr, 10); //10 the the length of the new array
System.out.println(Arrays.toString(copied));
 
copied = Arrays.copyOf(arr, 3);
System.out.println(Arrays.toString(copied));

Producción:

[1, 2, 3, 4, 5, 0, 0, 0, 0, 0]
[1, 2, 3]

2. La principal diferencia

La diferencia es que Arrays.copyOf no solo copia elementos, también crea una nueva matriz. System.arrayCopy copia en una matriz existente.

Si leemos el código fuente de Arrays.copyOf (), podemos ver que usa System.arraycopy().

public static int[] copyOf(int[] original, int newLength) { 
   int[] copy = new int[newLength]; 
   System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); 
   return copy; 
}

Categorías
Array

Imprimir una matriz en Java

Esta publicación resume 5 formas diferentes de imprimir una matriz en Java.

5 formas diferentes de imprimir una matriz

Arrays.toString(arr)
for(int n: arr) 
   System.out.println(n+", ");
for (int i = 0; i < arr.length; i++) {
   System.out.print(arr[i] + ", ");
}
System.out.println(Arrays.asList(arr));
Arrays.asList(arr).stream().forEach(s -> System.out.println(s));

El ganador

Aparentemente, el primero es bastante simple. Si una matriz es multidimensional, es decir, contiene matrices como elementos, podemos usar Arrays.deepToString() para imprimir la matriz:

System.out.println(Arrays.deepToString(arr));