• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Wstawianie do listy elementów innej listy

Fiszki IT
Fiszki IT
0 głosów
80 wizyt
pytanie zadane 30 maja w Java przez cba Użytkownik (550 p.)

Witam, mam problem z tym jak umieścić elementy listy B do listy A przy pomocy iteratora a także iterując w tył usunąć elementy listy A i znowu wypisać zawartość.

Oto mój kod...

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class ListyZadDom
{
    public static void main(String args []){
        List<String> A= new ArrayList<String>();
        A.add("1");
        A.add("2");
        A.add("3");
        A.add("4");
        List<String> B= new ArrayList<String>();
        B.add("A");
        B.add("B");
        B.add("C");
        B.add("D");
        ListIterator<String> iterator = A.listIterator();

        while(iterator.hasNext()){
        iterator.next();
        A.add(B);
        }

        System.out.println(A);

        }
        }

 

1 odpowiedź

+2 głosów
odpowiedź 30 maja przez HaKIM Szeryf (87,790 p.)
edycja 30 maja przez HaKIM

Po pierwsze, czytaj i staraj się zrozumieć błędy zwracane przez program.
Po drugie, czytaj dokumentacje używanych przez Ciebie komponentów.

Metoda listIterator zwraca obiekt ListIterator typu elementu wywołującej jej listy - w tym przypadku String.

ListIterator<String>

Obiekt ListIterator zawiera następujące metody:

https://www.tutorialspoint.com/java/java_using_iterator.htm

Teraz, gdy zaznajomimy się z działaniem każdej z metod możemy wywnioskować, że będziemy potrzebować kolejno hasNextadd i next.

No więc tworzymy pętle:

while(iterator.hasNext()) {
    ...
}

Wewnątrz pętli chcemy dodać elementy listy "B".

Instrukcja, którą próbowałeś, A.add(B) nie zadziałała, gdyż A jest typu ArrayList a jej metoda add przyjmuje argumenty element typu String oraz opcjonalnie index typu Int podczas gdy próbujesz dodać element typu ArrayList<String> (patrz typ zmiennej B).

Gdybyś zrozumiał błąd, który program Ci zwrócił, wiedziałbyś o tym.

Będąc wzbogaconym o tę wiedzę, możemy przystąpić do solucji. 

Zacznijmy od mniej eleganckiej wersji:

...
ListIterator<String> bIterator = B.listIterator();

while(iterator.hasNext()) {
    while (bIterator.hasNext()) {
        iterator.add(bIterator.next());
    }
    
    iterator.next(); // Zalecam jednak wykonanie instrukcji "break" w tym przypadku. Output ten sam, natomiast program zyska na optymalizacji a iterator nadal jest w grze.
}

Wiemy, że B ma elementy tego samego typu co A, więc metoda A.add(elementB) zadziała. Stąd, jeżeli chcemy wykazać się fanatyzmem dla podejścia z użyciem iteratorów, tworzymy bIterator a następnie przypisujemy elementy bIterator do iterator (Sugerowałbym nazwy bIterator i aIterator, ale to inna sprawa).

Powyższy program zadziała.

Teraz czas na solucję bardziej elegancką, przy okazji podkreślającą, że znajomość dokumentacji obiektów z którymi pracujemy jest istotna.

Zapoznawszy się z dokumentacją obiektu ArrayList wiem, że zawiera ona metodę addAll((Collection(? Extends E) c). Znając typy listy A i B oraz wymagany typ parametru c metody addAll wiemy, że poniższy kod zadziała:

...
B.add("C");
B.add("D");

A.addAll(B);
System.out.println(A);

Link do dokumentacji: https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html

Z resztą zadań zostawiam Cię sam, jestem pewny, że uda Ci się rozwiązać resztę zadań, jeśli podejdziesz do tematu z chęcią zgłębienia pisanych przez siebie programów i używanych przez niego zasobów jak biblioteka java.

EDIT

Kolega Subtelny podsunął mi, że trafniejszym rozwiązaniem tego problemu jest program poniżej:

List<String> A = new ArrayList<>();
A.add("1");
A.add("2");
A.add("3");
A.add("4");

List<String> B = new ArrayList<>();
B.add("A");
B.add("B");
B.add("C");
B.add("D");

ListIterator<String> bListIterator = B.listIterator();
bListIterator.forEachRemaining(A::add);

System.out.println(Arrays.toString(A.toArray()));

Metoda forEachRemaining: https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html

Usunięcie elementów iteratora B z elementów listy A pozostawiam jako ćwiczenie, co powinno być prostsze z tym rozwiązaniem.

komentarz 31 maja przez cba Użytkownik (550 p.)
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class ListyZadDom
{
    public static void main(String[] args){
        List<String> A= new ArrayList<>();
        A.add("1");
        A.add("2");
        A.add("3");
        A.add("4");
        List<String> B= new ArrayList<>();
        B.add("A");
        B.add("B");
        B.add("C");
        B.add("D");
        ListIterator<String> aIterator = A.listIterator();

        ListIterator<String> bIterator = B.listIterator();
        int i=0 ,j=0;
        while(aIterator.hasNext()) {
            i++;
            if (i % 2 == 0) {
                aIterator.next();
                aIterator.add(bIterator.next());

            }
        }
        System.out.println(A);

        while (j<8)
        {
            aIterator.previous();
            j++;
            if(j%2==0)
            {
                aIterator.remove();

            }

        }
        System.out.println(A);
    }
}

Zrobiłem to w ten sposób bo miały być naprzemiennie dodawane elementy, jednak problem jest jeśli listy nie są tej samej długości. Próbowałem to jakoś rozwiązać if-ami ale nic nie chciało działać właściwie. Nie mam pomysłu jak można to zrobić. 

komentarz 31 maja przez HaKIM Szeryf (87,790 p.)
    val A: MutableList<String> = arrayListOf("1", "2")
    val B: MutableList<String> = arrayListOf("A", "B", "C", "D")

    val bListIterator: ListIterator<String> = B.listIterator()

    var position = 0
    while (bListIterator.hasNext()) {
        if (position > A.size) {
            A.add(bListIterator.next())
            continue
        }

        A.add(position, bListIterator.next())
        position += 2
    }

    println(A)

    while (bListIterator.hasPrevious()) {
        A.remove(bListIterator.previous())
    }

    println(A)

Program napisany w języku Kotlin/JVM, więc nie powinieneś mieć problemu ze zrozumieniem.

Myślę, że program jest zrozumiały oprócz pierwszego warunku w pierwszej pętli while - sprawdzam tam czy docelowa pozycja elementu B przekroczy wielkość tablicy A. Bez tego warunku mógłbyś spotkać się z IndexOutOfBounds exception.

Jeżeli masz pewność, że tablice A i B będą miały taką samą wielkość, możesz usunąć ten warunek.

Szczerze powiedziawszy, nie podoba mi się ten kod, głównie przez ifa sprawdzającego wielkość tablicy przeciwko docelowej pozycji - może ktoś znajdzie lepsze rozwiązanie.

Podobne pytania

0 głosów
1 odpowiedź 646 wizyt
pytanie zadane 12 września 2016 w Java przez Patryk Rafał Bywalec (2,700 p.)
0 głosów
0 odpowiedzi 1,012 wizyt
pytanie zadane 13 stycznia 2018 w Java przez Kasia Nowicjusz (230 p.)
Porady nie od parady
Publikując kody źródłowe korzystaj ze specjalnego bloczku koloryzującego składnię (przycisk z napisem code w edytorze). Nie zapomnij o ustawieniu odpowiedniego języka z rozwijanego menu oraz czytelnym formatowaniu kodu.Przycisk code

84,744 zapytań

133,548 odpowiedzi

295,964 komentarzy

56,007 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...