Effectief wisselen van elementen van een array in Java

Ik vraag me af of er een efficiëntere manier is om twee elementen in een array te verwisselen dan zoiets als dit te doen:

String temp = arr[1];
arr[1] = arr[2];
arr[2] = temp;

Nou, dit is natuurlijk niet slecht of zelfs verkeerd, maar ik moet heel vaak ruilen, dus ik ben geïnteresseerd of er Libs of iets zijn die een efficiëntere manier bieden om dit te doen?


Antwoord 1, autoriteit 100%

Nee. Je zou een functie kunnen hebben om het beknopter te maken op elke plaats waar je het gebruikt, maar uiteindelijk zou het verrichte werk hetzelfde zijn (plus de overhead van de functieaanroep, totdat/tenzij HotSpot het inline verplaatst — om het te helpen met dat, maak de functie static final).


Antwoord 2, autoriteit 91%

Dit zou het naadloos moeten maken:

public static final <T> void swap (T[] a, int i, int j) {
  T t = a[i];
  a[i] = a[j];
  a[j] = t;
}
public static final <T> void swap (List<T> l, int i, int j) {
  Collections.<T>swap(l, i, j);
}
private void test() {
  String [] a = {"Hello", "Goodbye"};
  swap(a, 0, 1);
  System.out.println("a:"+Arrays.toString(a));
  List<String> l = new ArrayList<String>(Arrays.asList(a));
  swap(l, 0, 1);
  System.out.println("l:"+l);
}

Antwoord 3, autoriteit 56%

Als je nummers verwisselt en een beknopte manier wilt om de code te schrijven zonder een aparte functie te maken of een verwarrende XOR-hack te gebruiken, vind ik dit veel gemakkelijker te begrijpen en het is ook een one-liner.

public static void swap(int[] arr, int i, int j) {
    arr[i] = (arr[i] + arr[j]) - (arr[j] = arr[i]);
}

Wat ik van sommige primitieve benchmarks heb gezien, is dat het prestatieverschil ook in principe verwaarloosbaar is.

Dit is een van de standaard manieren om array-elementen om te wisselen zonder een tijdelijke variabele te gebruiken, in ieder geval voor gehele getallen.


Antwoord 4, autoriteit 38%

Als je een string wilt verwisselen. het is al de efficiënte manier om dat te doen.

Als u echter gehele getallen wilt omwisselen, kunt u XOR gebruiken om twee gehele getallen efficiënter als volgt om te wisselen:

int a = 1; int b = 2; a ^= b; b ^= a; a ^= b;

Antwoord 5, autoriteit 19%

Gebruik Collections.swapen Arrays.asList:

Collections.swap(Arrays.asList(arr), i, j);

Antwoord 6, autoriteit 6%

inplace swapping (voor het geval je het nog niet wist) kan wat ruimte besparen door geen tijdelijke variabele te maken.

arr[i] = arr[i] + arr[j];
arr[j] = arr[i] - arr[j];
arr[i] = arr[i] - arr[j];

Antwoord 7, autoriteit 3%

Ongelooflijk laat voor de partij (mijn excuses), maar er kan een meer algemene oplossing worden geïmplementeerd dan hier wordt gegeven (werkt zowel met primitieven als met niet-primitieven):

public static void swap(final Object array, final int i, final int j) {
    final Object atI = Array.get(array, i);
    Array.set(array, i, Array.get(array, j));
    Array.set(array, j, atI);
}

Je verliest de veiligheid tijdens het compileren, maar het zou voldoende moeten zijn.

Opmerking I: u krijgt een NullPointerExceptionals de gegeven arraynullis, een IllegalArgumentExceptionals de gegeven arrayis geeneen array, en een ArrayIndexOutOfBoundsExceptionals een van de indices niet geldig is voor de gegeven array.

Opmerking II: het hebben van aparte methoden hiervoor voor elkarraytype (Object[]en alle primitieve typen) zou beter presteren (met behulp van de andere benaderingen die hier worden gegeven) omdat dit wat boksen/unboxen vereist. Maar het zou ook veel meer code zijn om te schrijven/onderhouden.


Antwoord 8, autoriteit 3%

Probeer dit:

   int lowIndex = 0;
    int highIndex = elements.length-1;
    while(lowIndex < highIndex) {
        T lowVal = elements[lowIndex];
        T highVal = elements[highIndex];
        elements[lowIndex] = highVal;
        elements[highIndex] = lowVal;
        lowIndex += 1;
        highIndex -=1;
    }

Antwoord 9

allereerst moet u for (int k = 0; k **<** data.length **- 1**; k++)niet schrijven omdat de < is totdat de k kleiner is dan de lengte -1 en dan loopt de lus tot de laatste positie in de array en krijgt hij niet de laatste plaats in de array;
dus je kunt het op twee manieren oplossen:
1: for (int k = 0; k <= data.length - 1; k++)
2: for (int k = 0; k < data.length; k++)en dan werkt het prima!!!
en om te wisselen kun je gebruiken: om een van de int’s op een andere plaats te houden en dan te vervangen

int x = data[k]
data[k] = data[data.length - 1]
data[data.length - 1] = x;

omdat je niet één van de int’s wilt verliezen!!


Antwoord 10

Oplossing voor object- en primitieve typen:

public static final <T> void swap(final T[] arr, final int i, final int j) {
    T tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final boolean[] arr, final int i, final int j) {
    boolean tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final byte[] arr, final int i, final int j) {
    byte tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final short[] arr, final int i, final int j) {
    short tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final int[] arr, final int i, final int j) {
    int tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final long[] arr, final int i, final int j) {
    long tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final char[] arr, final int i, final int j) {
    char tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final float[] arr, final int i, final int j) {
    float tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
public static final void swap(final double[] arr, final int i, final int j) {
    double tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}

Antwoord 11

Dit is gewoon een “hack”-methode:

int d[][] = new int[n][n];
static int swap(int a, int b) {
  return a;
}
...
in main class --> 
d[i][j + 1] = swap(d[i][j], d[i][j] = d[i][j + 1])

Antwoord 12

public class SwapElements {
public static void main(String[] args) {
    int[] arr1 = new int[5];
    int[] arr2 = {10,20,30,40};
    System.out.println("arr1 Before Swapping " + Arrays.toString(arr1));
    System.out.println("arr2 Before Swapping " + Arrays.toString(arr2));
    int temp[];
    arr1[3] = 5;
    arr1[0] = 2;
    arr1[1] = 3;
    arr1[2] = 6;
    arr1[4] = 10;
    temp = arr1;
    arr1 = arr2;
    arr2 = temp;
    System.out.println("arr1 after Swapping " + Arrays.toString(arr1));
    System.out.println("arr2 after Swapping " + Arrays.toString(arr2));
}

}

Other episodes