Question

Comment dois-je multiplier 10 à un Integer objet et d'en obtenir les Integer l'objet?

Je suis à la recherche de la plus élégante des manières de le faire.

Je serais probablement le faire de cette façon:Obtenez de l'int de Integer objet, de le multiplier avec les autres int et de créer un autre objet Integer avec cette valeur int.

Le Code sera quelque chose comme ...

integerObj = new Integer(integerObj.intValue() * 10);

Mais, j'ai vu un code où l'auteur est de le faire de cette façon:Obtenez de l' String à partir de la Integer objet, concaténer "0" à la fin et puis obtenir Integer l'objet en utilisant Integer.parseInt

Le code est quelque chose comme ceci:

String s = integerObj + "0";
integerObj = Integer.parseInt(s);

Est-ce là tout le mérite de le faire de toute façon?

Et ce qui serait le plus efficace/plus élégante façon, en général, et dans ce cas?

Était-ce utile?

La solution

Avec Java 5 l'autoboxing, vous pouvez tout simplement faire:

Integer a = new Integer(2); // or even just Integer a = 2;
a *= 10;
System.out.println(a);

Autres conseils

La chaîne approche est amusant, mais presque certainement une mauvaise façon de le faire.

L'obtention de l'int de la valeur d'un Entier, et la création d'un nouveau sera très rapide, où que parseInt serait assez cher à l'appel.

Dans l'ensemble, je serai d'accord avec votre approche originale (qui, comme d'autres l'ont souligné, il peut être fait sans l'encombrement si vous avez l'autoboxing introduite dans Java 5).

Le problème avec la deuxième voie est la façon dont les Chaînes sont traitées en Java:

  • "0" est converti en une Chaîne constante de l'objet au moment de la compilation.
  • Chaque fois que ce code est appelé, s est construit comme un nouvel objet de type String, et javac convertit le code de String s = new StringBuilder().append(integerObj.toString()).append("0").toString() (StringBuffer pour les anciennes versions).Même si vous utilisez le même integerObj, c'est à dire,

    String s1 = integerObj + "0"; String s2 = integerObj + "0";

    (s1 == s2) serait false, tandis que s1.equals(s2) serait true.

  • Integer.parseInt appelle en interne new Integer() de toute façon, parce que Integer est immuable.

BTW, l'autoboxing/unboxing est à l'intérieur la même que la première méthode.

Tenir à l'écart de la deuxième approche, le meilleur pari serait la l'autoboxing si vous êtes à l'aide de java 1.5, rien de plus tôt, votre premier exemple serait le mieux.

La solution à l'aide de la méthode de Chaîne n'est pas très bon pour une variété de raisons.Certains sont des raisons esthétiques, d'autres sont d'ordre pratique.

Sur un front pratique de plusieurs objets créés par la Chaîne de version de la plus à la forme normale (comme vous l'avez exprimé dans votre premier exemple).

Sur le plan esthétique, je pense que la deuxième version obscurcit l'intention du code et qui est presque aussi important que de le faire pour produire le résultat que vous souhaitez.

trousse d'outils de la réponse ci-dessus est correcte et le meilleur moyen, mais il ne donne pas une explication complète de ce qui se passe.En supposant que Java 5 ou d'une version ultérieure:

Integer a = new Integer(2); // or even just Integer a = 2;
a *= 10;
System.out.println(a); // will output 20

Ce que vous devez savoir, c'est que c'est exactement la même que le fait de faire:

Integer a = new Integer(2); // or even just Integer a = 2;
a = a.intValue() * 10;
System.out.println(a.intValue()); // will output 20

En effectuant l'opération (dans ce cas *=) sur l'objet "a", vous ne modifiez pas la valeur int à l'intérieur de la 'une' de l'objet, mais en réalité, l'affectation d'un nouvel objet "a".C'est parce que 'a' devient auto-unboxed afin d'effectuer la multiplication, puis le résultat de la multiplication devient auto-encadrées et attribué à 'a'.

Entier est un objet immuable.(Toutes les classes wrapper sont immuables.)

Prenons pour exemple ce morceau de code:

static void test() {
    Integer i = new Integer(10);
    System.out.println("StartingMemory: " + System.identityHashCode(i));
    changeInteger(i);
    System.out.println("Step1: " + i);
    changeInteger(++i);
    System.out.println("Step2: " + i.intValue());
    System.out.println("MiddleMemory: " + System.identityHashCode(i));
}

static void changeInteger(Integer i) {
    System.out.println("ChangeStartMemory: " + System.identityHashCode(i));
    System.out.println("ChangeStartValue: " + i);
    i++;
    System.out.println("ChangeEnd: " + i);
    System.out.println("ChangeEndMemory: " + System.identityHashCode(i));
}

La sortie sera:

StartingMemory: 1373539035
ChangeStartMemory: 1373539035
ChangeStartValue: 10
ChangeEnd: 11
ChangeEndMemory: 190331520
Step1: 10
ChangeStartMemory: 190331520
ChangeStartValue: 11
ChangeEnd: 12
ChangeEndMemory: 1298706257
Step2: 11
MiddleMemory: 190331520

Vous pouvez voir l'adresse en mémoire de " i " est en train de changer (vos adresses de mémoire sera différent).

Maintenant faisons un petit test avec la réflexion, ajoutez ceci à la fin de la méthode test ():

System.out.println("MiddleMemory: " + System.identityHashCode(i));
try {
    final Field f = i.getClass().getDeclaredField("value");
    f.setAccessible(true);
    f.setInt(i, 15);
    System.out.println("Step3: " + i.intValue());
    System.out.println("EndingMemory: " + System.identityHashCode(i));
} catch (final Exception e) {
    e.printStackTrace();
}

La production supplémentaire sera:

MiddleMemory: 190331520
Step2: 15
MiddleMemory: 190331520

Vous pouvez voir que l'adresse en mémoire de " je " n'a pas changé, même si nous avons changé sa valeur à l'aide de la réflexion.
(NE PAS UTILISER DE RÉFLEXION DE CETTE FAÇON DANS LA VRAIE VIE!!)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top