„Java“ sąrašo metodų pamoka - „Util List“ API pavyzdys

Sąrašai yra paprastai naudojamos duomenų struktūros kiekvienoje programavimo kalboje.

Šioje pamokoje mes ištirsime „Java“ sąrašo API. Pradėsime nuo pagrindinių operacijų ir tada pradėsime pažangesnius dalykus (pvz., Skirtingų sąrašų tipų palyginimą, pvz., „ArrayList“ ir „LinkedList“).

Taip pat pateiksiu keletą gairių, kurios padės pasirinkti sąrašo įgyvendinimą, kuris geriausiai tinka jūsų situacijai.

Nors vadovaujantis pamoka pakanka pagrindinių „Java“ žinių, paskutiniame skyriuje reikalingos pagrindinės duomenų struktūros („Array“, „LinkedList“) ir „Big-O“ žinios. Jei su jomis nesate susipažinę, nedvejodami praleiskite tą skyrių.

Sąrašų apibrėžimas

Sąrašai yra užsakomi objektų rinkiniai. Ta prasme jie yra panašūs į matematikos sekas. Tačiau jie nepanašūs į rinkinius, kurie neturi tam tikros tvarkos.

Keletas dalykų, kuriuos reikia nepamiršti: sąrašuose leidžiama turėti dublikatus ir nulinius elementus. Jie yra nuorodų arba objektų tipai ir, kaip ir visi „Java“ objektai, jie saugomi kaupe.

„Java“ sąrašas yra sąsaja ir yra daugybė sąrašų tipų, kurie įgyvendina šią sąsają.

Pirmuose pavyzdžiuose naudosiu „ArrayList“, nes tai dažniausiai naudojamas sąrašo tipas.

„ArrayList“ iš esmės yra masyvas, kurio dydį galima keisti. Beveik visada norite naudoti „ArrayList“ per įprastus masyvus, nes jie pateikia daug naudingų metodų.

Vienintelis masyvo pranašumas anksčiau buvo jų fiksuotas dydis (neskiriant daugiau vietos nei reikia). Tačiau dabar sąrašai taip pat palaiko fiksuotus dydžius.

Kaip sukurti sąrašą Java

Pakanka kalbėtis, pradėkime nuo savo sąrašo sukūrimo.

import java.util.ArrayList; import java.util.List; public class CreateArrayList { public static void main(String[] args) { ArrayList list0 = new ArrayList(); // Makes use of polymorphism List list = new ArrayList(); // Local variable with "var" keyword, Java 10 var list2 = new ArrayList(); } }

Kampiniuose skliaustuose () nurodome objektų, kuriuos ketiname laikyti, tipą.

Atminkite, kad skliaustuose nurodytas tipas turi būti objekto, o ne primityvus . Todėl turime naudoti objektų įklijas, „Integer“ klasę vietoj int, „Double“, o ne dvigubą, ir pan.

Yra daug būdų sukurti „ArrayList“, tačiau aukščiau pateiktame fragmente pateikiau tris įprastus būdus.

Pirmasis būdas yra sukurti objektą iš konkrečios „ArrayList“ klasės nurodant „ArrayList“ kairėje užduoties pusėje.

Antrasis kodo fragmentas naudoja polimorfizmą naudodamas kairėje pusėje pateiktą sąrašą. Tai daro užduotį laisvai sujungtą su „ArrayList“ klase ir leidžia mums priskirti kitų tipų sąrašus ir lengvai pereiti prie kitokio sąrašo įgyvendinimo.

Trečias būdas yra „Java 10“ būdas kurti vietinius kintamuosius naudojant raktinį žodį var. Kompiliatorius interpretuoja kintamojo tipą, patikrindamas dešinę pusę.

Matome, kad visos užduotys yra to paties tipo:

System.out.println(list0.getClass()); System.out.println(list.getClass()); System.out.println(list2.getClass());

Išvestis:

class java.util.ArrayList class java.util.ArrayList class java.util.ArrayList 

Taip pat galime nurodyti pradinį sąrašo pajėgumą.

List list = new ArrayList(20);

Tai naudinga, nes kai sąrašas pasipildo ir bandote pridėti kitą elementą, dabartinis sąrašas nukopijuojamas į naują sąrašą, kurio talpa yra dvigubai didesnė už ankstesnio sąrašo talpą. Visa tai vyksta užkulisiuose.

Ši operacija vis dėlto daro mūsų sudėtingumą O (n) , todėl norime to išvengti. Numatytasis pajėgumas yra 10, taigi, jei žinote, kad saugosite daugiau elementų, turėtumėte nurodyti pradinį pajėgumą.

Kaip pridėti ir atnaujinti sąrašo elementus „Java“

Norėdami įtraukti elementus į sąrašą, galime naudoti pridėjimo metodą. Mes taip pat galime nurodyti naujo elemento indeksą, tačiau būkime atsargūs tai darydami, nes tai gali sukelti „ IndexOutOfBoundsException“ .

import java.util.ArrayList; public class AddElement { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add("hello"); list.add(1, "world"); System.out.println(list); } }

Išvestis:

[hello, world]

Elementui atnaujinti galime naudoti nustatytą metodą.

list.set(1, "from the otherside"); System.out.println(list);

Išvestis:

[hello, world] [hello, from the otherside]

Kaip gauti ir ištrinti sąrašo elementus

Gauti iš sąrašo elementą, galite naudoti get metodu ir pateikti elemento, kurį norite gauti indeksą.

import java.util.ArrayList; import java.util.List; public class GetElement { public static void main(String[] args) { List list = new ArrayList(); list.add("hello"); list.add("freeCodeCamp"); System.out.println(list.get(1)); } }

Išvestis:

freeCodeCamp 

Šios operacijos sudėtingumas „ArrayList“ yra O (1), nes fone naudojama įprasta atsitiktinės prieigos masyvas.

Norėdami pašalinti elementą iš „ArrayList“, naudojamas pašalinimo metodas.

list.remove(0);

Tai pašalina indekso 0 elementą, kuris šiame pavyzdyje yra „labas“.

Mes taip pat galime vadinti šalinimo metodą su elementu, kad jį surastume ir pašalintume. Atminkite, kad jis pašalina pirmą elemento atsiradimą tik tuo atveju, jei jis yra.

public static void main(String[] args) { List list = new ArrayList(); list.add("hello"); list.add("freeCodeCamp"); list.add("freeCodeCamp"); list.remove("freeCodeCamp"); System.out.println(list); }

Išvestis:

[hello, freeCodeCamp]

Norėdami pašalinti visus įvykius, mes galime naudoti metodą „ removeAll “ tuo pačiu būdu.

Šie metodai yra sąsajos sąraše, todėl kiekviena sąrašo realizacija juos turi (ar tai būtų „ArrayList“, ar „LinkedList“, ar „Vector“).

Kaip gauti „Java“ sąrašo ilgį

Norėdami gauti sąrašo ilgį arba elementų skaičių,galime naudoti dydžio () metodą.

import java.util.ArrayList; import java.util.List; public class GetSize { public static void main(String[] args) { List list = new ArrayList(); list.add("Welcome"); list.add("to my post"); System.out.println(list.size()); } } 

Išvestis:

2

Dviejų matmenų „Java“ sąrašai

Galima sukurti dviejų matmenų sąrašus, panašius į 2D matricas.

ArrayList
    
      listOfLists = new ArrayList();
    

Šią sintaksę naudojame kurdami sąrašų sąrašą, o kiekviename vidiniame sąraše saugomi sveikieji skaičiai. Bet mes dar neinicijavome vidinių sąrašų. Turime patys juos susikurti ir įtraukti į šį sąrašą:

int numberOfLists = 3; for (int i = 0; i < numberOfLists; i++) { listOfLists.add(new ArrayList()); }

Inicializuoju savo vidinius sąrašus ir šiuo atveju pridedu 3 sąrašus. Be to, jei reikia, sąrašus galiu pridėti vėliau.

Dabar mes galime įtraukti elementus į savo vidinius sąrašus. Norėdami pridėti elementą, pirmiausia turime gauti nuorodą į vidinį sąrašą.

Pavyzdžiui, tarkime, kad norime pridėti elementą į pirmąjį sąrašą. Turime gauti pirmąjį sąrašą, tada jį papildyti.

listOfLists.get(0).add(1);

Štai jums pavyzdys. Pabandykite atspėti žemiau esančio kodo segmento išvestį:

public static void main(String[] args) { ArrayList
    
      listOfLists = new ArrayList(); System.out.println(listOfLists); int numberOfLists = 3; for (int i = 0; i < numberOfLists; i++) { listOfLists.add(new ArrayList()); } System.out.println(listOfLists); listOfLists.get(0).add(1); listOfLists.get(1).add(2); listOfLists.get(2).add(0,3); System.out.println(listOfLists); }
    

Išvestis:

[] [[], [], []] [[1], [2], [3]]

Atkreipkite dėmesį, kad sąrašus galima atsispausdinti tiesiogiai (skirtingai nuo įprastų masyvų), nes jie nepaiso toString () metodo.

Naudingi „Java“ metodai

Yra keletas kitų naudingų metodų ir nuorodų, kurie dažnai naudojami. Šiame skyriuje noriu jus supažindinti su kai kuriais iš jų, kad jums būtų lengviau dirbti su sąrašais.

Kaip sukurti „Java“ elementų sąrašą

It is possible to create and populate the list with some elements in a single line. There are two ways to do this.

The following is the old school way:

public static void main(String[] args) { List list = Arrays.asList( "freeCodeCamp", "let's", "create"); }

You need to be cautious about one thing when using this method: Arrays.asList returns an immutable list. So if you try to add or remove elements after creating the object, you will get an UnsupportedOperationException.

You might be tempted to use final keyword to make the list immutable but it won't work as expected.

It just makes sure that the reference to the object does not change – it does not care about what is happening inside the object. So it permits inserting and removing.

final List list2 = new ArrayList(); list2.add("erinc.io is the best blog ever!"); System.out.println(list2);

Output:

[erinc.io is the best blog ever!] 

Now let's look at the modern way of doing it:

ArrayList friends = new ArrayList(List.of("Gulbike", "Sinem", "Mete")); 

The List.of method was shipped with Java 9. This method also returns an immutable list but we can pass it to the  ArrayList constructor to create a mutable list with those elements. We can add and remove elements to this list without any problems.

How to Create a List with N Copies of Some Element in Java

Java provides a method called NCopies that is especially useful for benchmarking. You can fill an array with any number of elements in a single line.

public class NCopies { public static void main(String[] args) { List list = Collections.nCopies(10, "HELLO"); System.out.println(list); } }

Output:

[HELLO, HELLO, HELLO, HELLO, HELLO, HELLO, HELLO, HELLO, HELLO, HELLO] 

How to Clone a List in Java

As previously mentioned, Lists are reference types, so the rules of passing by reference apply to them.

public static void main(String[] args) { List list1 = new ArrayList(); list1.add("Hello"); List list2 = list1; list2.add(" World"); System.out.println(list1); System.out.println(list2); }

Output:

[Hello, World] [Hello, World]

The list1 variable holds a reference to the list. When we assign it to list2 it also points to the same object. If we do not want the original list to change, we can clone the list.

ArrayList list3 = (ArrayList) list1.clone(); list3.add(" Of Java"); System.out.println(list1); System.out.println(list3);

Output:

[Hello, World] [Hello, World, Of Java]

Since we cloned list1, list3 holds a reference to its clone in this case. Therefore list1 remains unchanged.

How to Copy a List to an Array in Java

Sometimes you need to convert your list to an array to pass it into a method that accepts an array. You can use the following code to achieve that:

List list = new ArrayList(List.of(1, 2)); Integer[] toArray = list.toArray(new Integer[0]);

You need to pass an array and the toArray method returns that array after filling it with the elements of the list.

How to Sort a List in Java

To sort a list we can use Collections.sort. It sorts in ascending order by default but you can also pass a comparator to sort with custom logic.

List toBeSorted = new ArrayList(List.of(3,2,4,1,-2)); Collections.sort(toBeSorted); System.out.println(toBeSorted);

Output:

[-2, 1, 2, 3, 4]

How do I choose which list type to use?

Before finishing this article, I want to give you a brief performance comparison of different list implementations so you can choose which one is better for your use case.

We will compare ArrayList, LinkedList and Vector. All of them have their ups and downs so make sure you consider the specific context before you decide.

Java ArrayList vs LinkedList

Here is a comparison of runtimes in terms of algorithmic complexity.

| | ArrayList | LinkedList | |-----------------------|----------------------------|------------| | GET(index) | O(1) | O(n) | | GET from Start or End | O(1) | O(1) | | ADD | O(1), if list is full O(n) | O(1) | | ADD(index) | O(n) | O(1) | | Remove(index) | O(n) | O(1) | | Search and Remove | O(n) | O(n) |

Generally, the get operation is much faster on ArrayList but add and remove are faster on LinkedList.

ArrayList uses an array behind the scenes, and whenever an element is removed, array elements need to be shifted (which is an O(n) operation).

Choosing data structures is a complex task and there is no recipe that applies to every situation. Still, I will try to provide some guidelines to help you make that decision easier:

  • If you plan to do more get and add operations other than remove, use ArrayList since the get operation is too costly on LinkedList. Keep in mind that insertion is O(1) only if you call it without specifying the index and add to the end of the list.
  • If you are going to remove elements and/or insert in the middle (not at the end) frequently, you can consider switching to a LinkedList because these operations are costly on ArrayList.
  • Keep in mind that if you access the elements sequentially (with an iterator), you will not experience a performance loss with LinkedList while getting elements.

Java ArrayList vs Vector

Vector is very similar to ArrayList. If you are coming from a C++ background, you might be tempted to use a Vector, but its use case is a bit different than C++.

Vector's methods have the synchronized keyword, so Vector guarantees thread safety whereas ArrayList does not.

You might prefer Vector over ArrayList in multithreaded programming or you can use ArrayList and handle the synchronization yourself.

In a single-threaded program, it is better to stick with ArrayList because thread-safety comes with a performance cost.

Conclusion

In this post, I have tried to provide an overview of Java's List API. We have learned to use basic methods, and we've also looked at some more advanced tricks to make our lives easier.

Mes taip pat palyginome „ArrayList“, „LinkedList“ ir „Vector“, kurie yra dažniausiai užduodama tema interviu metu.

Ačiū, kad skyrėte laiko perskaityti visą straipsnį, ir tikiuosi, kad jis buvo naudingas.

Visą kodą galite pasiekti iš šios saugyklos.

Jei jus domina daugiau tokių straipsnių skaitymas, galite užsiprenumeruoti mano tinklaraščio adresų sąrašą ir gauti pranešimą, kai aš paskelbsiu naują straipsnį.