¿Algún atajo para inicializar todos los elementos de la matriz a cero?

282

En lo C/C++que solía hacer

int arr[10] = {0};

... para inicializar todos mis elementos de matriz a 0.

¿Hay un atajo similar en Java?

Quiero evitar usar el bucle, ¿es posible?

int arr[] = new int[10];
for(int i = 0; i < arr.length; i++) {
    arr[i] = 0;
}
juego terminado
fuente
2
java.util.Arrays.fill () int [] arr = new int [10]; e int arr [10] = {0}; Todos usan bucles internos.
Kevin Kostlan

Respuestas:

574

La especificación del idioma garantiza un valor predeterminado de 0 para las matrices de tipos integrales :

Cada variable de clase, variable de instancia, o componente de matriz se inicializa con un valor predeterminado cuando se crea (§15.9, §15.10) [...] Para el tipo int, el valor predeterminado es cero, es decir, 0.  

Si desea inicializar una matriz unidimensional a un valor diferente, puede usar java.util.Arrays.fill () (que por supuesto usará un bucle internamente).

Michael Borgwardt
fuente
@MichaelBorgwardt Fue una respuesta útil para mí. ¿Tendría el mismo costo de hacerlo en comparación con for loop?
maytham-ɯɐɥʇʎɐɯ
@ maytham-ɯɐɥıλɐɯ: puedes mirar el código fuente, viene con el JDK. Es exactamente lo mismo, el método consiste en nada más que un bucle for perfectamente normal y directo.
Michael Borgwardt
@MichaelBorgwardt ¿Qué pasa con los valores de una matriz bidimensional local? ¿Eso cae bajo "componente de matriz"?
Rishi
Arrays.fillno necesariamente usa un bucle.
Nates
@NateS: ¿puede dar un ejemplo de una implementación de Java que no lo haga?
Michael Borgwardt
105

Si bien las otras respuestas son correctas (los valores de la matriz int se inicializan por defecto a 0), si desea hacerlo explícitamente (por ejemplo, si desea una matriz llena con el valor 42), puede usar el método fill () de la clase Arrays :

int [] myarray = new int[num_elts];
Arrays.fill(myarray, 42);

O si eres un fanático de 1-liners, puedes usar la Collections.nCopies()rutina:

Integer[] arr = Collections.nCopies(3, 42).toArray(new Integer[0]);

Daría arr el valor:

[42, 42, 42]

(aunque es Integer, y no int, si necesita el tipo primitivo, puede diferir a la rutina Apache CommonsArrayUtils.toPrimitive() :

int [] primarr = ArrayUtils.toPrimitive(arr);
Adam Parkin
fuente
9
Las frases sencillas son buenas, pero ¿ List<Integer>para Integer[]qué int[]? Eso es un poco complicado.
dhardy
2
@dhardy Claro, pero es por eso que también hay una versión de 2 líneas en la respuesta (si le preocupa el factor "complicado").
Adam Parkin
Inicializar la matriz 2D con el Arrays.fillmétodo está creando un problema y se produce un error.
AKS
39

En Java todos los elementos (tipos enteros primitivos byte short, int, long) se inicializan a 0 por defecto. Puedes guardar el bucle.

Arne Deutsch
fuente
2
¡¿Supongo que esto vale para los tipos primitivos ?!
Olimpiu POP
1
Los tipos de Java primitivos, como int, no se inicializan.
Mirko Ebert
8
@ tfb785: Esto está mal. Como se indicó anteriormente por Michael Borgwardt: los tipos enteros primitivos (short, int, long) se inicializan a 0.
Arne Deutsch
1
Sí, la matriz de primitivas de Java como int [] se inicia con 0. No, un tipo de primitiva de Java no se inicia con 0.
Mirko Ebert
3
Ok, para ser precisos: los miembros de clase primitivos (ya sea estáticos o no) se inicializan con 0. Las variables locales no lo son.
Arne Deutsch
23

¿Cómo reduce el rendimiento de su aplicación ...? Leer a continuación.

En la especificación del lenguaje Java, el valor predeterminado / inicial para cualquier objeto se puede dar como sigue.

Para el tipo byte , el valor predeterminado es cero , es decir, el valor de (byte) es 0 .

Para el tipo short , el valor predeterminado es cero , es decir, el valor de (short) es 0 .

Para el tipo int , el valor predeterminado es cero , es decir, 0 .

Para el tipo largo , el valor predeterminado es cero , es decir, 0L .

Para el tipo flotante , el valor predeterminado es cero positivo , es decir, 0.0f .

Para el tipo doble , el valor predeterminado es cero positivo , es decir, 0.0d .

Para el tipo char , el valor predeterminado es el carácter nulo , es decir, ' \ u0000 '.

Para el tipo booleano , el valor predeterminado es falso .

Para todos los tipos de referencia , el valor predeterminado es nulo .

Al considerar todo esto, no necesita inicializar con valores cero para los elementos de la matriz porque, de forma predeterminada, todos los elementos de la matriz son 0 para int array.

Porque Una matriz es un objeto contenedor que contiene un número fijo de valores de un solo tipo. Ahora el tipo de matriz para usted es int, por lo tanto, considere que el valor predeterminado para todos los elementos de la matriz será automáticamente 0 porque contiene int type .

Ahora considere la matriz para el tipo de cadena para que todos los elementos de la matriz tengan un valor predeterminado es nulo .

¿Por qué no haces eso ......?

puede asignar un valor nulo utilizando el bucle como sugiere en su Pregunta.

int arr[] = new int[10];
for(int i=0;i<arr.length;i++)
    arr[i] = 0;

Pero si lo hace, será una pérdida inútil del ciclo de la máquina. y si utiliza en su aplicación donde tiene muchas matrices y lo hace para cada matriz, afectará el rendimiento de la aplicación hasta un nivel considerable.

El mayor uso del ciclo de la máquina ==> Más tiempo para procesar los datos ==> El tiempo de salida aumentará significativamente . para que el procesamiento de datos de su aplicación pueda considerarse como un nivel bajo (Reduzca la velocidad hasta cierto nivel).

Jugal Thakkar
fuente
17

Puede guardar el ciclo, la inicialización ya está hecha a 0. Incluso para una variable local.

Pero corrija el lugar donde coloca los corchetes, para facilitar la lectura (mejor práctica reconocida):

int[] arr = new int[10];
KLE
fuente
14

Si está utilizando Float o Integer, puede asignar un valor predeterminado como este ...

Integer[] data = new Integer[20];
Arrays.fill(data,new Integer(0));
Pankaj Goyal
fuente
6

Puede crear una nueva matriz vacía con su tamaño de matriz existente, y puede asignarlos nuevamente a su matriz. Esto puede ser más rápido que otro. Snipet:

package com.array.zero;
public class ArrayZero {
public static void main(String[] args) {
    // Your array with data
    int[] yourArray = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    //Creating same sized array with 0
    int[] tempArray = new int[yourArray.length];
    Assigning temp array to replace values by zero [0]
    yourArray = tempArray;

    //testing the array size and value to be zero
    for (int item : yourArray) {
        System.out.println(item);
    }
}
}

Resultado:

0
0
0
0
0    
0
0
0
0
Kavishankar Karunakaran
fuente
1

Sí, los valores int en una matriz se inicializan a cero. Pero no tienes garantizado esto. La documentación de Oracle indica que esta es una mala práctica de codificación.

nate
fuente
De acuerdo con la especificación del lenguaje Java, sección 15.10.2 , si una matriz se crea con una excepción de creación de matriz que no proporciona valores iniciales, entonces todos los elementos de la matriz se inicializan al valor predeterminado para el tipo de componente de la matriz, es decir, 0 en el caso de char []. Esto es una garantia; Me sorprendería bastante que Oracle considerara que confiar en él es una mala práctica.
Ian Robertson
1

Los valores int ya son cero después de la inicialización, como todos han mencionado. Si tiene una situación en la que realmente necesita establecer los valores de la matriz a cero y desea optimizar eso, use System.arraycopy:

static private int[] zeros = new float[64];
...
int[] values = ...
if (zeros.length < values.length) zeros = new int[values.length];
System.arraycopy(zeros, 0, values, 0, values.length);

Esto se utiliza memcpydebajo de las cubiertas en la mayoría o en todas las implementaciones de JRE. Tenga en cuenta que el uso de una estática como esta es segura incluso con múltiples subprocesos, ya que el peor de los casos es que varios subprocesos se reasignen zerossimultáneamente, lo que no hace daño a nada.

También podría usar Arrays.fillcomo algunos otros han mencionado. Arrays.fill podría usarse memcpyen una JVM inteligente, pero probablemente sea solo un bucle de Java y la comprobación de límites que conlleva.

Compare sus optimizaciones, por supuesto.

Nates
fuente
1

Otro enfoque más usando lambda sobre java 8

 Arrays.stream(new Integer[nodelist.size()]).map(e -> 
 Integer.MAX_VALUE).toArray(Integer[]::new);
brahmananda Kar
fuente
1

En c / cpp no ​​hay acceso directo sino inicializar todas las matrices con el subíndice cero.

  int arr[10] = {0};

Pero en java hay una herramienta mágica llamada Arrays.fill () que llenará todos los valores en una matriz con el entero de su elección.

  import java.util.Arrays;

    public class Main
    {
      public static void main(String[] args)
       {
         int ar[] = {2, 2, 1, 8, 3, 2, 2, 4, 2};
         Arrays.fill(ar, 10);
         System.out.println("Array completely filled" +                          
            " with 10\n" + Arrays.toString(ar));
   }
 }
Ansh Srivastava
fuente
1

La inicialización no es necesaria en caso de cero porque el valor predeterminado de int en Java es cero. Para valores distintos de cero, java.util.Arraysofrece una serie de opciones, la más simple es el método de relleno.

int[] arr = new int[5];
Arrays.fill(arr, -1);
System.out.println(Arrays.toString(arr));  //[-1, -1, -1, -1, -1 ]

int [] arr = new int[5];
// fill value 1 from index 0, inclusive, to index 3, exclusive
Arrays.fill(arr, 0, 3, -1 )
System.out.println(Arrays.toString(arr)); // [-1, -1, -1, 0, 0]

También podemos usar Arrays.setAll () si queremos completar el valor en función de la condición:

int[] array = new int[20];
Arrays.setAll(array, p -> p > 10 ? -1 : p);

int[] arr = new int[5];
Arrays.setAll(arr, i -> i);
System.out.println(Arrays.toString(arr));   // [0, 1, 2, 3, 4]
Shreya Sharma
fuente
0

declare la matriz como variable de instancia en la clase, es decir, fuera de cada método y JVM le dará 0 como valor predeterminado. No necesitas preocuparte más

Dhruvam Gupta
fuente
-3
    int a=7, b=7 ,c=0,d=0;
    int dizi[][]=new int[a][b];
    for(int i=0;i<a;i++){
        for(int q=d;q<b;q++){
            dizi[i][q]=c;               
            System.out.print(dizi[i][q]);
            c++;
        }

        c-=b+1;
        System.out.println();               
    }

resultado 0123456 -1012345 -2-101234 -3-2-10123 -4-3-2-1012 -5-4-3-2-101 -6-5-4-3-2-10

Ubeyd
fuente