2015-08-01 27 views
5

Sono un principiante. Questa potrebbe essere una domanda stupida.Perché "big = big.add (..)" deve essere usato per sommare BigIntegers?

Ho una serie di numeri veramente grandi. Devo trovare la somma di tutti quei numeri nell'array. Ho definito un BigInteger e inizializzato a zero. Ora attraverserò la matrice e aggiungerò ogni elemento a questo BigInteger.

BigInteger big = BigInteger.ZERO; 
for(BigInteger b : array){ 
    big.add(b); 
} 

Nessun errore di compilazione, ma big valore era ancora pari a zero, il codice non ha funzionato. Così, ho controllato e ho imparato che il metodo di aggiunta di BigInteger restituisce la somma. Ho modificato sopra il codice.

big = big.add(b); 

Ora questo ha funzionato bene.

La mia domanda: Che cosa sta realmente accadendo lì? Perché il primo codice non ha aggiornato il valore big.

Posso paragonare questa BigInteger.add() con collection.add()

un quadro più chiaro è apprezzato. Grazie.

risposta

8

Perché il primo codice non ha aggiornato un grande valore.

BigInteger è immutabile, non è possibile modificarlo più di quanto sia possibile modificare una stringa o un qualsiasi involucro primitivo.

ad es.

String s = "Hello "; 
s.concat("World"); // doesn't change anything. 

s = s.concat("World"); // Updates 's' 

Posso paragonare questa BigInteger.add() con la collezione.add()

Le raccolte sono modificabili, ma questo valore scalare non lo è.

L'utilizzo di oggetti mutabili è in gran parte una concessione di prestazioni. Se hai una collezione che prende una copia completa ogni volta che si comporterebbe molto male.

+0

Può per favore elaborare una concessione di prestazioni? Grazie. – Charan

+1

@Charan La creazione di una nuova raccolta contenente quasi esattamente gli stessi riferimenti di una esistente potrebbe essere costosa se la raccolta è ampia. Le raccolte mutabili consentono di ottenere una versione leggermente modificata di una raccolta senza fare quel lavoro. –

+1

@Charan Aggiungere un elemento a un ArrayList di un milione di elementi potrebbe essere semplice come un'assegnazione di riferimento e un incremento del contatore. Per copiare e aggiungere, devi copiare tutti i riferimenti, tutti milioni solo per aggiungerne uno. BTW CopyOnWriteArrayList esegue questa operazione ed è molto lento per la modifica di una raccolta di grandi dimensioni. –

2

La mia domanda: che cosa sta realmente accadendo lì? Perché il primo codice non ha aggiornato il grande valore.

Perché è immutabili interi precisione arbitraria significa che non sarà effettivamente cambiare quello originale, ma crearne uno nuovo quando si chiama add method.Note mezzi immutabili per cui una volta che il Object viene creato suo stato non può essere changed.For esempio String, Integer, Float ecc

Integer i = new Integer(10);//State 1 
i = new Integer(20);//State 2 but does not update state 1 

big.add(b); restituisce valore dopo l'aggiunta che è necessario memorizzare in un altro o lo stesso variabile.

Vedere che cosa aggiungere metodo sta facendo qui,

public BigInteger add(BigInteger val) { 
    if (val.signum == 0) 
     return this; 
    if (signum == 0) 
     return val; 
    if (val.signum == signum) 
     return new BigInteger(add(mag, val.mag), signum); 

    int cmp = compareMagnitude(val); 
    if (cmp == 0) 
     return ZERO; 
    int[] resultMag = (cmp > 0 ? subtract(mag, val.mag) 
         : subtract(val.mag, mag)); 
    resultMag = trustedStripLeadingZeroInts(resultMag); 
    //Here it's creating new Object 
    return new BigInteger(resultMag, cmp == signum ? 1 : -1);//<==== 
} 

Posso paragonare questa BigInteger.add() con Collection.add()

Qui dicono List.add sarà effettivamente aggiungere l'elemento alla lista e puoi cambiare il valore di quell'elemento e nota List.add non crea un nuovo elemento ma in realtà aggiunge il riferimento dell'elemento originale.

4

Questa è la JavaDoc per il metodo

public BigInteger add(BigInteger val) 
Returns a BigInteger whose value is (this + val). 

Parameters: 
val - value to be added to this BigInteger. 

Returns: 
this + val 

Ciò significa che invece di modificare il valore, si calcola un nuovo valore e restituisce. Quando esegui , stai eseguendo quel metodo, prendendo il valore risultante e sostituendo il valore originale di grande con esso.

Considerare l'equivalente utilizzando ints, xey.

int x = 3; 
int y = 4; 
x + y; // At this point, x is still 3 - as you've not assigned the result of this calculation anywhere 
x = x + y; // Now - x will be 7