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
ncalorí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.
intno 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, MutableStringetc, pero en cambio tienen una Mutable<Integer>, Mutable<Double>, ... La sobrecarga de la memoria (de utilizar Integermás de intlo 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.
intes siempre mutable a menos que también lo seafinal
Integer a = 4;entonces a = 5;es un código válido, pero Integerno es mutable.
Integerinstancias no son mutables incluso si las referencias a ellas lo son, pero ese es un tipo diferente.
intno 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
AtomicIntegerya se ha mencionado. DoubleSe 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 ResultSetcomputadora 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.reduceo 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.
fory foreachpueden 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