Loendi ümberpööramine Javas – kohapeal ja väljaspool

Sellest lühikesest õpetusest saate teada, kuidas Javas loendit paigas ja mittekohal ümber pöörata.

Tagurdamine paigas ja paigast väljas

Loenditega toimingute tegemisel võiksite kaaluda, kas toimingud tehakse kohapeal (muudatused tehakse algses objektis) või on need kohatud (muudatused tehakse koopial ja originaalis objekt on muutumatu).

Mõned keeled ja teegid eelistavad erinevat vaikekäitumist. Java puhul on enamik tagurpidi loendite toiminguid kohas.

Kui see on teie soovitud käitumine - suurepärane! Kui ei, siis soovite enne koopia tagasipööramist luua loendist koopia.

List list = new ArrayList(Arrays.asList(1, 2, 3));
List listCopy = new ArrayList(list);

Märge: . clone() meetod ei luua sügav koopia. Loendi koostamine kasutades new ArrayList(list) ei luua sügav koopia. Sügavate koopiate loomine on ebasoovitav ja üllatavalt keeruline üldisel viisil (ja mõnel juhul pole sellel mõtet, olenevalt loendis olevast andmetüübist). See ei takista teil tagurdamist list ja mitte omama elemente listCopy olles siiski vastupidine.

Collections.reverse()

. Collections.reverse() meetod on kogu tagasipööramise standardmeetod ja toimib kui "kadunud" List.reverse() meetod. See muudab loendi paigas:

List list = new ArrayList(Arrays.asList(1, 2, 3));
List listCopy = new ArrayList(list);

Collections.reverse(list);

System.out.println(list);     
System.out.println(listCopy); 

Guajaavi nimekirjad.reverse(loend)

Kui kasutate Google Guava't juba oma projektis, saate ka seda kasutada Lists klass, mis pakub reverse() meetod, mis ei sorteeri algset loendit paigas, vaid loob koopia ja pöörab koopia ümber:

List list = new ArrayList(Arrays.asList(1, 2, 3));
List reversedList = Lists.reverse(list);

System.out.println(list);         
System.out.println(reversedList); 

Kui teil seda veel pole, saate Maveni abil oma projekti lisada Google Guava, lisades selle sõltuvuse oma pom.xml faili:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
</dependency>

Või Gradle'i kaudu:

implementation group: 'com.google.guava', name: 'guava'

Märge: Kui teil ei ole veel Google Guava't või te ei kavatse seda kasutada oma projekti muude osade jaoks – ärge importige seda ainult selle toimingu jaoks ja pidage kinni Collections.reverse() meetod. Guajaav on suur sõltuvus ja see on suur liialdus, kui seda kasutada ainult selle toimingu jaoks.

List.add() ja List.remove()

Kui soovite lisaks loendi ümberpööramisele teha täiendavaid toiminguid, saate algset loendit korrata, eemaldada elemendid lõpust, edastada need suvalise meetodi kaudu ja lisada need uuesti loendi algusesse:


public static int process(int input) {
    return input;
}

List list = new ArrayList(Arrays.asList(1, 2, 3));

for (int i = 0, j = list.size()-1; i <= j; i++) {
    int lastValue = process(list.remove(j));
    list.add(i, lastValue);
}

System.out.println(list);  

võrrelda

Niisiis, mis on kiireim? See sõltub ka sellest, kas soovite toimingut teha kohapeal või väljaspool.

In-Place Reversal etalon

Võrdleme mõlemat lähenemisviisi kõigi kolme meetodi puhul, alustades kohatust:

List list = new Random().ints(100, 1, 11)
                .boxed()
                .collect(Collectors.toList());

int runs = 1000;

long start1 = System.currentTimeMillis();
for (int i = 0; i < runs; i++) {
    reverseListCollections(list);
}
long end1 = System.currentTimeMillis();
System.out.println(String.format("Collections.reverse() took: %s miliseconds", end1-start1));

long start2 = System.currentTimeMillis();
for (int i = 0; i < runs; i++) {
    reverseListGuava(list);
}
long end2 = System.currentTimeMillis();
System.out.println(String.format("Guava's Lists.reverse() took: %s miliseconds", end2-start2));

long start3 = System.currentTimeMillis();
for (int i = 0; i < runs; i++) {
    reverseListManually(list);
}
long end3 = System.currentTimeMillis();
System.out.println(String.format("Manually took: %s miliseconds", end3-start3));

System.out.println("Original list: " + list);

Selle tulemuseks on:

Collections.reverse() took: 3 miliseconds
Guava's Lists.reverse() took: 4 miliseconds
Manually took: 13 miliseconds
Original list: [6, 7, 9, 7, 2, 5, 4, 1, 3, 2, 2, 6, ...

Tutvuge meie praktilise ja praktilise Giti õppimise juhendiga, mis sisaldab parimaid tavasid, tööstusharus aktsepteeritud standardeid ja kaasas olevat petulehte. Lõpetage Giti käskude guugeldamine ja tegelikult õppima seda!

Mis juhtub, kui suurendame elementide arvu 100-lt 1000-le?

Collections.reverse() took: 9 miliseconds
Guava's Lists.reverse() took: 4 miliseconds
Manually took: 133 miliseconds
Original list: [10, 2, 2, 6, 2, 4, 7, 3, 9, 2, 7, 5, ...

Guajaav säilitab 4 ms märgi! Manuaalsel lähenemisel on kõige halvem ajaline keerukus ja see tõusis lineaarselt. Collections.reverse() kannatavad suurendamise tõttu vähem, kuid Guava rakendamine kannatab kõige vähem. Pidage siiski meeles, et me ei kopeeri loendit käsitsi Guava lähenemisviisi jaoks. Kas võrdlusalus muutub, kui loobume ideest originaalse ja ümberpööratud loendi loomisest?

Kohavälise tagasipööramise võrdlusalus

1000 elemendiga, millest igaüks töötab loendi mittepööratud koopial (mis jäeti ajamõõtmistest välja), kui eemaldame igast meetodist käsitsi koopia ja käivitame koodi uuesti:

Collections.reverse() took: 7 miliseconds
Guava's Lists.reverse() took: 3 miliseconds
Manually took: 131 miliseconds
Original list: [6, 8, 10, 7, 3, 8, 7, 1, 1, 9, 5, ...

Guajaav veel suudab järjekindlalt mõlemat edestada Collections.reverse() ja käsitsi lähenemine.

Järeldus

Sellest lühikesest juhendist õppisite, kuidas Java-vormingus loendit ümber pöörata, nii paigas kui ka väljas, säilitades toimingu algse loendi. Oleme kasutanud Collections.reverse() meetod, Google Guava's Lists.reverse() meetod ja käsitsi lähenemine.

Ajatempel:

Veel alates Stackabus