Estoy en una situación en la que quiero usar versiones mutables de cosas como Integer. ¿Tengo que usar estas clases (a continuación) o Java tiene algo integrado?
http://www.java2s.com/Code/Java/Data-Type/Amutableintwrapper.htm
Estoy en una situación en la que quiero usar versiones mutables de cosas como Integer. ¿Tengo que usar estas clases (a continuación) o Java tiene algo integrado?
http://www.java2s.com/Code/Java/Data-Type/Amutableintwrapper.htm
n
calorías, que se pueden agotar / agregar), podría ser mejor usar una clase con el nombre del uso (p. Ej. class FoodItem { int calories; }
, Porque es más claro y los métodos pueden ser agregado si es necesario más tarde.
int
no funciona como si se incrementara en un método, entonces el valor no se reflejará en el otro método.
Respuestas:
No, Java no los tiene integrados. Y eso es por una razón. Usar tipos mutables es peligroso, ya que se pueden usar incorrectamente fácilmente. Además, es muy fácil de implementar. Por ejemplo, commons-lang tiene la extensión MutableInt
.
Siempre puede envolver el valor en una matriz como int[] mutable = {1};
si incluir el código para una clase contenedora mutable fuera demasiado engorroso.
Desde JDK 1.5 java ahora tiene java.util.concurrent.atomic.AtomicInteger
Este es un entero mutable seguro para subprocesos, ejemplo de uso:
final AtomicInteger value = new AtomicInteger(0);
luego más tarde:
value.incrementAndGet();
Aquí hay una pequeña clase que hice para un entero mutable:
public class MutableInteger {
private int value;
public MutableInteger(int value) {
this.value = value;
}
public void set(int value) {
this.value = value;
}
public int intValue() {
return value;
}
}
Fácilmente podría extender esto a cualquier otro primitivo. Por supuesto, como dicen todos los demás, debes usarlo con cuidado.
MutableInteger
, MutableDouble
, MutableString
etc, pero en cambio tienen una Mutable<Integer>
, Mutable<Double>
, ... La sobrecarga de la memoria (de utilizar Integer
más de int
lo general no caer en la cuenta. Pero obtienes una clase única, lista para usar que puede manejar la mayoría de los casos (aunque si quieres que tu número entero sea comparable o cosas similares, aún necesitas subclase).
Puede usar un nnnn [] como un objeto mutable para cualquier tipo primitivo como sugiere @Alexandre, java también tiene AtomicInteger y AtomicLong.
En mi humilde opinión, int suele ser una mejor opción que Integer y eso es mutable.
¿Puede obtener más detalles de por qué necesita un objeto múltiple? Quizás haya otra forma de lograr lo mismo.
int
es siempre mutable a menos que también lo seafinal
Integer a = 4;
entonces a = 5;
es un código válido, pero Integer
no es mutable.
Integer
instancias no son mutables incluso si las referencias a ellas lo son, pero ese es un tipo diferente.
int
no es mutable porque si lo pasa a un método, no hay forma de que el método cambie su valor y refleje el nuevo valor en el método de llamada
AtomicInteger
ya se ha mencionado. Double
Se puede emular un s mutable AtomicReference<Double>
. Se aplican las advertencias ya mencionadas y es de mal estilo, pero a veces tienes un código como este
double sum=0
for (Data data:someListGenerator())
sum+=data.getValue()
y desea refactorizarlo en estilo funcional Java 8. Si el código sigue este patrón pero le agrega una complejidad considerable, la conversión más sensata podría ser
AtomicReference<Double> sumref=new AtomicReference<>(0d);
someStreamGenerator().forEach(data->
sumref.set(sumref.get().doubleValue()+data.getValue()));
double sum=sumref.get().doubleValue();
Por supuesto, este es al menos un estilo cuestionable. Pero me encontré más de una vez en una situación con un bucle retorcido sobre una ResultSet
computadora y en parte acumulando tres datos diferentes. Esto hace que sea realmente difícil convertir el código en un estilo funcional adecuado. Convertir las partes acumuladas de acuerdo con el patrón anterior me pareció una compensación razonable entre un código limpio y una refactorización demasiado simplificada.
someStreamGenerator().mapToDouble(Data::getValue).sum()
. Incluso para acumular tres informaciones diferentes, existe una forma funcional mediante el uso de Stream.reduce
o Stream.collect
. No veo ninguna razón para refactorizar cada bucle en un fragmento de código funcional, pero si quiere ir por ese camino, debe hacerlo hasta el final.
for
y foreach
pueden ser partes de marcos complejos que se reescriben funcionalmente, por lo que debe alinear el resto del código de alguna manera alrededor de ellos.
Puede importar el paquete org.omg.CORBA (o solo la clase que necesita) y en él puede usar las clases de Holder.
Por ejemplo, tiene el "IntHolder" donde el campo donde almacena el entero es público, dando acceso para modificarlo.
public static void triple(IntHolder x){
x.value = 3 * x.value;
}
IntHolder mutableInt = new IntHolder(10);
triple(mutableInt);
System.out.println(mutableInt.value);
También tiene "LongHolder" y "DoubleHolder" y muchos otros que puedes usar. Úselo con precaución.
Aquí está la API para ello: https://docs.oracle.com/javase/7/docs/api/org/omg/CORBA/package-summary.html