Bez duplikata
Učitava se n, pa n celih brojeva. Ispisati brojeve bez ponavljanja, redom kojim su se prvi put pojavili.
Primer
Ulaz
8
3 1 3 7 1 1 9 7Izlaz
3 1 7 9Niz ima fiksnu dužinu koja se zadaje pri pravljenju. Kada broj elemenata nije unapred poznat, koristi se lista iz paketa java.util: elementi se dodaju i uklanjaju, a lista sama raste. Ovde su ArrayList, LinkedList, prolazak kroz listu, sortiranje i poređenje objekata.
U uglastim zagradama navodi se tip elemenata (generički tip). Za proste tipove koriste se klase omotači: Integer umesto int, Double umesto double, Character umesto char.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> imena = new ArrayList<>();
imena.add("Ana"); // dodaje na kraj
imena.add("Marko");
imena.add("Iva");
imena.add(1, "Luka"); // umeće na poziciju 1
System.out.println(imena + " velicina " + imena.size());
System.out.println("Na poziciji 2: " + imena.get(2));
imena.set(0, "Ana Marija"); // menja element
imena.remove("Iva"); // uklanja po vrednosti
imena.remove(0); // uklanja po poziciji
System.out.println(imena);
System.out.println("Sadrzi Marko? " + imena.contains("Marko") + ", pozicija " + imena.indexOf("Marko"));
}
}
| Niz | ArrayList |
|---|---|
int[] a = new int[10]; | List<Integer> a = new ArrayList<>(); |
a.length | a.size() |
a[i] | a.get(i) |
a[i] = x; | a.set(i, x); |
| dužina je fiksna | a.add(x), a.remove(i) |
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList<Integer> brojevi = new ArrayList<>();
// učitavaj dok ne dođe 0 – broj elemenata nije unapred poznat
int x;
while ((x = sc.nextInt()) != 0)
brojevi.add(x);
int zbir = 0;
for (int b : brojevi) // for-each
zbir += b;
System.out.println("Ucitano " + brojevi.size() + ", zbir " + zbir);
// klasična petlja kada treba indeks
for (int i = 0; i < brojevi.size(); i++)
if (brojevi.get(i) > zbir / brojevi.size())
System.out.println("iznad proseka: " + brojevi.get(i) + " (pozicija " + i + ")");
// uklanjanje u toku prolaska: removeIf (ne remove u for-each petlji!)
brojevi.removeIf(b -> b % 2 == 0);
System.out.println("Neparni: " + brojevi);
}
}
Uklanjanje elemenata u for-each petlji baca ConcurrentModificationException. Koristi removeIf sa uslovom (lambda izraz b -> b % 2 == 0 čita se „element b takav da je paran“) ili petlju unazad po indeksu.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> a = new ArrayList<>(List.of(5, 2, 9, 1, 7));
Collections.sort(a); // rastuće
System.out.println(a);
a.sort(Comparator.reverseOrder()); // opadajuće
System.out.println(a);
System.out.println("max=" + Collections.max(a) + " min=" + Collections.min(a));
List<String> reci = new ArrayList<>(List.of("sljiva", "kivi", "jabuka", "dunja"));
Collections.sort(reci); // abecedno
System.out.println(reci);
reci.sort(Comparator.comparing(String::length)); // po dužini (stabilno)
System.out.println(reci);
}
}
List.of(...) pravi listu koja se ne može menjati; zato se njeni elementi kopiraju u new ArrayList<>(...).
Za sopstvene klase redosled se zadaje Comparator-om. Metode comparing i thenComparing grade poređenje po više polja:
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
public class Main {
// record: kratak zapis klase sa poljima, konstruktorom, geterima i toString (Java 16+)
record Ucenik(String ime, int razred, double prosek) { }
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
List<Ucenik> lista = new ArrayList<>();
for (int i = 0; i < n; i++)
lista.add(new Ucenik(sc.next(), sc.nextInt(), Double.parseDouble(sc.next())));
// po razredu rastuće, pa po proseku opadajuće, pa po imenu
lista.sort(Comparator.comparingInt(Ucenik::razred)
.thenComparing(Ucenik::prosek, Comparator.reverseOrder())
.thenComparing(Ucenik::ime));
for (Ucenik u : lista)
System.out.println(u.razred() + ". " + u.ime() + " " + u.prosek());
}
}
Ucenik::razred je referenca na metodu – kraći zapis za u -> u.razred(). Više o tome u lekciji Lambda izrazi i Stream API.
LinkedList je povezana lista: dodavanje i uklanjanje na početku i kraju je brzo, ali je get(i) spor (prolazi od početka). Za red (queue) i stek u Javi se preporučuje ArrayDeque:
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;
public class Main {
public static void main(String[] args) {
// red: prvi ušao – prvi izašao (FIFO)
Queue<String> red = new LinkedList<>();
red.offer("Ana");
red.offer("Marko");
red.offer("Iva");
System.out.println("Na redu je: " + red.poll() + ", ostali: " + red);
// stek: poslednji ušao – prvi izašao (LIFO)
Deque<Character> stek = new ArrayDeque<>();
String izraz = "(a+[b*c])";
boolean ispravno = true;
for (char c : izraz.toCharArray()) {
if (c == '(' || c == '[')
stek.push(c);
else if (c == ')' || c == ']') {
char otv = c == ')' ? '(' : '[';
if (stek.isEmpty() || stek.pop() != otv)
ispravno = false;
}
}
System.out.println(izraz + (ispravno && stek.isEmpty() ? " ispravne zagrade" : " neispravne zagrade"));
}
}
| Operacija | ArrayList | LinkedList |
|---|---|---|
get(i) | brzo | sporo (n koraka) |
| dodavanje na kraj | brzo | brzo |
| dodavanje/uklanjanje na početku | sporo (pomeranje svih) | brzo |
U praksi se najčešće koristi ArrayList.
Za svaki zadatak postoji primer, uputstvo i rešenje. Rešenja su provereno tačna na primerima iz teksta.
Učitava se n, pa n celih brojeva. Ispisati brojeve bez ponavljanja, redom kojim su se prvi put pojavili.
8
3 1 3 7 1 1 9 73 1 7 9Učitava se n, pa za svakog takmičara ime i broj poena. Ispisati rang listu: više poena je bolje, a kod istog broja poena redosled je abecedni. Takmičari sa istim brojem poena dele isto mesto (posle dva druga mesta sledi četvrto).
5
Marko 80
Ana 95
Iva 80
Luka 60
Sara 801. Ana 95
2. Iva 80
2. Marko 80
2. Sara 80
5. Luka 60List<int> je greška, piše se List<Integer>.List<Integer> poziv remove(3) uklanja element na poziciji 3; vrednost 3 se uklanja sa remove(Integer.valueOf(3)).removeIf.Integer objekta poredi sa equals (ili ih pretvori u int), ne sa ==.1. Kako se dobija broj elemenata ArrayList-e a?
2. Koja deklaracija je ispravna?
3. Šta je stek?
4. Kojom metodom se sortira lista lista?