studio - new icon java
¿Cómo hago mi función de intercambio en Java? (7)
AFAIS, nadie menciona la referencia atómica .
Entero
public void swap(AtomicInteger a, AtomicInteger b){
a.set(b.getAndSet(a.get()));
}
Cuerda
public void swap(AtomicReference<String> a, AtomicReference<String> b){
a.set(b.getAndSet(a.get()));
}
¿Cómo hago mi función de intercambio en Java si no hay un método por el cual podamos pasar por referencia? ¿Alguien podría darme un código?
swap(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
pero el cambio no se reflejará desde que java pasa por valor
Aparentemente no tengo suficientes puntos de reputación para comentar la respuesta de Dansalmo , pero es buena, aunque mal nombrada. Su respuesta es en realidad un K-combinator.
int K( int a, int b ) {
return a;
}
El JLS es específico sobre la evaluación de argumentos al pasar a methods / ctors / etc. (¿No era así en especificaciones más antiguas?)
Por supuesto, este es un modismo funcional , pero es lo suficientemente claro para aquellos que lo reconocen. (Si no entiende el código que encuentra, ¡no lo engañe!)
y = K(x, x=y); // swap x and y
El K-combinator está específicamente diseñado para este tipo de cosas. AFAIK no hay razón para que no pase una revisión del código.
Mi $ 0.02.
Creo que esto es lo más cerca que puedes llegar a un intercambio simple, pero no tiene un patrón de uso directo:
int swap(int a, int b) { // usage: y = swap(x, x=y);
return a;
}
y = swap(x, x=y);
Se basa en el hecho de que x
pasará al swap
antes de que y
se asigne a x
, luego x
se devuelve y se asigna a y
.
Puede hacerlo genérico e intercambiar cualquier cantidad de objetos del mismo tipo:
<T> T swap(T... args) { // usage: z = swap(a, a=b, b=c, ... y=z);
return args[0];
}
c = swap(a, a=b, b=c)
Depende de lo que quieras hacer. Este código intercambia dos elementos de una matriz.
void swap(int i, int j, int[] arr) {
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
Algo así intercambia el contenido de dos int[]
de igual longitud.
void swap(int[] arr1, int[] arr2) {
int[] t = arr1.clone();
System.arraycopy(arr2, 0, arr1, 0, t.length);
System.arraycopy(t, 0, arr2, 0, t.length);
}
Algo así intercambia el contenido de dos BitSet
(usando el algoritmo de intercambio XOR ):
void swap(BitSet s1, BitSet s2) {
s1.xor(s2);
s2.xor(s1);
s1.xor(s2);
}
Algo como esto intercambia los campos y
de alguna clase de Point
:
void swapXY(Point p) {
int t = p.x;
p.x = p.y;
p.y = t;
}
No puede crear un intercambio de método, por lo que después de llamar a swap(x,y)
se intercambiarán los valores de x e y. Podría crear dicho método para clases mutables intercambiando sus contenidos¹, pero esto no cambiaría su identidad de objeto y no podría definir un método general para esto.
Sin embargo, puede escribir un método que canjee dos elementos de una matriz o lista si eso es lo que desea.
¹ Por ejemplo, podría crear un método de intercambio que tome dos listas y luego de ejecutar el método, la lista x tendrá los contenidos previos de la lista y y la lista y tendrá los contenidos previos de la lista x.
Podría hacer algo como lo siguiente. Por supuesto, con la riqueza de las clases de Colección, no puedo imaginar que alguna vez necesite usar esto en cualquier código práctico.
public class Shift {
public static <T> T[] left (final T... i) {
if (1 >= i.length) {
return i;
}
final T t = i[0];
int x = 0;
for (; x < i.length - 1; x++) {
i[x] = i[x + 1];
}
i[x] = t;
return i;
}
}
Llamado con dos argumentos, es un intercambio.
Se puede usar de la siguiente manera:
int x = 1;
int y = 2;
Integer[] yx = Shift.left(x,y);
Alternativamente:
Integer[] yx = {x,y};
Shift.left(yx);
Entonces
x = yx[0];
y = yx[1];
Nota: autocarta primitivas.
Prueba esta magia
public static <T> void swap(T a, T b) {
try {
Field[] fields = a.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object temp = field.get(a);
field.set(a, field.get(b));
field.set(b, temp);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
¡Y pruébalo!
System.out.println("a:" + a);
System.out.println("b:" + b);
swap(a,b);
System.out.println("a:" + a);
System.out.println("b:" + b);