Fjernelse af elementer fra Java-samlinger

1. Oversigt

I denne hurtige vejledning vi skal tale om fire forskellige måder at fjerne emner fra Java på Samlinger der matcher bestemte prædikater.

Vi vil naturligvis også se på nogle af forbeholdene.

2. Definition af vores samling

For det første skal vi illustrere to tilgange, der muterer den oprindelige datastruktur. Derefter taler vi om to andre muligheder, der i stedet for at fjerne elementerne opretter en kopi af originalen Kollektion uden dem.

Lad os bruge følgende samling gennem vores eksempler for at demonstrere, hvordan vi kan opnå det samme resultat ved hjælp af forskellige metoder:

Samlingsnavne = ny ArrayList (); names.add ("John"); names.add ("Ana"); names.add ("Mary"); names.add ("Anthony"); names.add ("Mark");

3. Fjernelse af elementer med Iterator

Java'er Iterator gør det muligt for os både at gå og fjerne hvert enkelt element inden for en Kollektion.

For at gøre det skal vi først hente en iterator over dens elementer ved hjælp af iterator metode. Derefter kan vi besøge hvert element ved hjælp af Næste og fjern dem ved hjælp af fjerne:

Iterator i = names.iterator (); mens (i.hasNext ()) {String e = i.next (); hvis (e.startsWith ("A")) {i.remove (); }}

På trods af sin enkelhed er der nogle advarsler, vi bør overveje:

  • Afhængigt af samlingen kan vi støde på ConcurrentModificationException undtagelser
  • Vi er nødt til at gentage elementerne, inden vi kan fjerne dem
  • Afhængigt af samlingen, fjerne kan opføre sig anderledes end forventet. F.eks.: ArrayList.Iterator fjerner elementet fra samlingen og skifter efterfølgende data til venstre, mens, LinkedList.Iterator justerer blot markøren til det næste element. Som sådan, LinkedList.Iterator klarer sig meget bedre end ArrayList.Iterator når du fjerner genstande

4. Java 8 og Collection.removeIf ()

Java 8 introducerede en ny metode til det Kollektion interface, der giver en mere kortfattet måde at fjerne elementer ved hjælp af Prædikat:

names.removeIf (e -> e.startsWith ("A"));

Det er vigtigt at bemærke, at i modsætning til Iterator nærme sig, fjerneHvis fungerer lige godt i begge LinkedList og ArrayList.

I Java 8, ArrayList tilsidesætter standardimplementeringen - som er afhængig af Iterator - og implementerer en anden strategi: For det første går den over elementerne og markerer dem, der matcher vores Prædikat; bagefter gentager det en anden gang at fjerne (og skifte) de elementer, der blev markeret i den første iteration.

5. Java 8 og introduktionen af Strøm

En af de nye hovedfunktioner i Java 8 var tilføjelsen af Strøm (og Samlere). Der er mange måder at oprette en Strøm fra en kilde. Imidlertid er de fleste operationer, der påvirker Strøm eksempel vil ikke mutere sin kilde, snarere fokuserer API'et på at oprette kopier af en kilde og udføre enhver handling, vi måtte have brug for i dem.

Lad os se på, hvordan vi kan bruge Strøm og Samlere for at finde / filtrere elementer, der matcher og ikke matcher vores Prædikat.

5.1. Fjernelse af elementer med Strøm

Fjernelse, eller rettere, filtreringselementer ved hjælp af Strøm er ret ligetil, vi skal bare oprette en forekomst af Strøm bruger vores Kollektion, påberåbe sig filter med vores Prædikat og så indsamle resultatet ved hjælp af Samlere:

Samling filteredCollection = navne .stream () .filter (e ->! E.startsWith ("A")) .collect (Collectors.toList ());

Streaming er mindre invasiv end de tidligere tilgange, det fremmer isolering og muliggør oprettelse af flere kopier fra den samme kilde. Vi skal dog huske på, at det også øger den hukommelse, der bruges af vores applikation.

5.2. Collectors.partitioningBy

Kombinerer begge dele Stream.filter og Samlere er dog ganske praktisk vi kan løbe ind i scenarier, hvor vi har brug for både matchende og ikke-matchende elementer. I sådanne tilfælde kan vi drage fordel af Collectors.partitioningBy:

Kort classifiedElements = names .stream () .collect (Collectors.partitioningBy ((String e) ->! e.startsWith ("A"))); String matching = String.join (",", classifiedElements.get (true)); String nonMatching = String.join (",", classifiedElements.get (false));

Denne metode returnerer a Kort der kun indeholder to nøgler, rigtigt og falsk, der hver peger på en liste, der indeholder henholdsvis matchende og ikke-matchende elementer.

6. Konklusion

I denne artikel kiggede vi på nogle metoder til at fjerne elementer fra Samlinger og nogle af deres forbehold.

Du kan finde den komplette kildekode og alle kodestykker til denne artikel på GitHub.