Java - jak vymazat z ArrayListu množinu položek

Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Java - jak vymazat z ArrayListu množinu položek
« Odpověď #15 kdy: 22. 09. 2019, 11:10:17 »
Popravdě řečeno, nenapadá mě případ užití toho, co požaduješ. Evidentně si pleteš pojmy pole a seznam, z toho vzniká tohle zmatení.

ArrayList implementuje rozhraní List. Má rozhraní List metodu pro odstranění prvku podle indexu? Nemá, tak ji laskavě nepoužívej.
Já tam tu metodu vidím. Jsi si jist, že víš, o čem mluvíš?


Re:Java - jak vymazat z ArrayListu množinu položek
« Odpověď #16 kdy: 22. 09. 2019, 11:21:39 »
Popravdě řečeno, nenapadá mě případ užití toho, co požaduješ. Evidentně si pleteš pojmy pole a seznam, z toho vzniká tohle zmatení.

ArrayList implementuje rozhraní List. Má rozhraní List metodu pro odstranění prvku podle indexu? Nemá, tak ji laskavě nepoužívej.
Já tam tu metodu vidím. Jsi si jist, že víš, o čem mluvíš?

Neví. Tupě aplikuje nějakou Bobovskou poučku.

A ano, ta metoda existuje. A i kdyby nebyla, tak není důvod ji nepoužít, protože kód byl pro ArrayList a ne List. (Nic proti programování na interface, ale ocamcaď pocamcaď. Kdyby nemělo smysl mít mezi implementacemi rozdíly, tak by nebylo potřeba mít různé implementace.)

Re:Java - jak vymazat z ArrayListu množinu položek
« Odpověď #17 kdy: 22. 09. 2019, 11:22:26 »
Proč bych to měl dělat takhle, když můžu použít čitelnější postup Standy Blábola? Viz.
https://forum.root.cz/index.php?topic=21857.msg317204#msg317204

Protoze v zadani je, ze se maji z listu prvky vymazat a ne ze se ma vytvorit novy list.
Navic je tu performance.

To ale Standa Blábol taky řeší:

(...)
Nebo si vyrob pomocny arraylist pro vsechny keys z keylistu a na puvodnim arraylistu zavolej removeAlll() Tehnle pristup je vhodny pokud je pocet klicu maly vzhledem k delce arraylistu.

Nepredpokladam, ze resis kazdou milisekundu, to by nebyly daove struktury tak blbe navrzene.

Re:Java - jak vymazat z ArrayListu množinu položek
« Odpověď #18 kdy: 22. 09. 2019, 11:23:16 »
Díky za odpovědi, vyřešil jsem jednoduše vytvořením nového ArrayListu. Šlo mi jen o to se ujistit, zda neexistuje nějaká metoda, kterou by se to dalo sfouknout na jednom řádku kódu.

Všimni si ještě, o co je to tak snažší, než když musíš modifikovat ten původní... A to nemluvíme o situaci, kdy bys ta data nějak sdílel.

gill

  • ****
  • 270
    • Zobrazit profil
    • E-mail
Re:Java - jak vymazat z ArrayListu množinu položek
« Odpověď #19 kdy: 22. 09. 2019, 19:49:21 »
Díky za odpovědi, vyřešil jsem jednoduše vytvořením nového ArrayListu. Šlo mi jen o to se ujistit, zda neexistuje nějaká metoda, kterou by se to dalo sfouknout na jednom řádku kódu.

možná nějakou knihovnou nebo přejít na Kotlin, v Kotlinu existuje metoda filterIndexed

Kód: [Vybrat]
val list = listOf("one", "two", "three", "four")
val toremove = setOf(1,2)
val filteredIdx = list.filterIndexed { index, _ -> index !in toremove  }
println(filteredIdx) // [one, four]

pokud vím, v Javě nic podobného není, ani v Guavě a podobných knihovnách. Musel bys vytvořit list indexů, ten přefiltrovat a potom namapovat. Možná by šel elegantně použít predikát "in" z Guavy. Záleží, jestli ti jde o jednoduchost nebo o výkon.


gill

  • ****
  • 270
    • Zobrazit profil
    • E-mail
Re:Java - jak vymazat z ArrayListu množinu položek
« Odpověď #20 kdy: 22. 09. 2019, 20:23:25 »
Když ty indexy seřadíš, tak při procházení od nejmenšího víš, o kolik jsou ty další posunuté, nebo při procházení od nejvyššího tě posunutí netrápí. Jak se na tohle můžeš ptát?

nebo procházet od největšího.

Kód: [Vybrat]
Collections.sort(toremove, Collections.reverseOrder());
for (int i : toremove)
    list.remove(i);

to je asi nejstručnější, ale nejsem si jistý složitostí. Jistější je vytvořit nový seznam.

Re:Java - jak vymazat z ArrayListu množinu položek
« Odpověď #21 kdy: 22. 09. 2019, 20:53:16 »
Jak se na tohle můžeš ptát?

Jak se na tohle můžeš ptát?

Jak se ho na to muzes ptat?

Re:Java - jak vymazat z ArrayListu množinu položek
« Odpověď #22 kdy: 22. 09. 2019, 20:56:13 »
Proč bych to měl dělat takhle, když můžu použít čitelnější postup Standy Blábola? Viz.
https://forum.root.cz/index.php?topic=21857.msg317204#msg317204

Protoze v zadani je, ze se maji z listu prvky vymazat a ne ze se ma vytvorit novy list.
Navic je tu performance.

To ale Standa Blábol taky řeší:

(...)
Nebo si vyrob pomocny arraylist pro vsechny keys z keylistu a na puvodnim arraylistu zavolej removeAlll() Tehnle pristup je vhodny pokud je pocet klicu maly vzhledem k delce arraylistu.

Nepredpokladam, ze resis kazdou milisekundu, to by nebyly daove struktury tak blbe navrzene.

Algoritmu, ktery jsem uvedl v prispevku, je maximalne efektivni a zaroven ten ArrayList modifikuje (nevytvari novy).
Coz, jak spravne bylo uvedeno v prispevku vyse, je klicova vlastnost pri sdileni teto struktury.
Ze zadani jsem se domnival, ze prave sdileni sktruktury nebo performance pozadavky implikuje "odstraneni polozek", nikoliv vytvoreni listu noveho.
Metoda ArrayList.removeAll() provadi remove v cyklu, coz zvysuje vypocetni slozitost.
Proto si dovolim pouziti removeAll povazovat za zbytecne plytvani. A prosim, debaty o tom, ze performance neni argument, jednoduse neberu.
Bohuzel se zda, ze dotaz vznikl pouze z nedostatecne znalosti, ikdyz to je moc pekny dotaz. Vyvozuji to z prijateho reseni.

Re:Java - jak vymazat z ArrayListu množinu položek
« Odpověď #23 kdy: 22. 09. 2019, 21:02:23 »
Kód: [Vybrat]
int[] itemsToRemove = {0, 5, 1, 4};
Arrays.sort(itemsToRemove);

for(int i = 0; i<itemsToRemove.length; i++) {
  list.remove(itemsToRemove[i] - i);
}

Re:Java - jak vymazat z ArrayListu množinu položek
« Odpověď #24 kdy: 22. 09. 2019, 22:11:57 »
Nebo:

Kód: [Vybrat]
int[] itemsToRemove = {0, 5, 1, 4};
Arrays.sort(itemsToRemove);
Arrays.reverse(itemsToRemove);

for(int i = 0; i<itemsToRemove.length; i++) {
  list.remove(itemsToRemove[i]);
}

Re:Java - jak vymazat z ArrayListu množinu položek
« Odpověď #25 kdy: 23. 09. 2019, 08:21:35 »
Algoritmu, ktery jsem uvedl v prispevku, je maximalne efektivni
Je dost odvážné tvrdit o něčem, že je to maximálně efektivní, když neznáte přesné zadání. Váš algoritmus ponechá původní velikost podkladového pole, takže není paměťově efektivní. Kdybyste to chtěl spravit zavoláním trimToSize(), bude zase výpočetně neefektivní (nevíte, zda to zmenšení pole není zbytečné).

Re:Java - jak vymazat z ArrayListu množinu položek
« Odpověď #26 kdy: 23. 09. 2019, 08:26:04 »
Nebo:

Kód: [Vybrat]
int[] itemsToRemove = {0, 5, 1, 4};
Arrays.sort(itemsToRemove);
Arrays.reverse(itemsToRemove);

for(int i = 0; i<itemsToRemove.length; i++) {
  list.remove(itemsToRemove[i]);
}
for-each cyklus je v Javě už 15 let.

gill

  • ****
  • 270
    • Zobrazit profil
    • E-mail
Re:Java - jak vymazat z ArrayListu množinu položek
« Odpověď #27 kdy: 23. 09. 2019, 12:44:54 »
Metoda ArrayList.removeAll() provadi remove v cyklu, coz zvysuje vypocetni slozitost.

removeAll hlavně dělá něco jiného, než na co se ptal tazatel. Odstraňuje položky podle hodnot, on chce odstranit podle indexů.

Re:Java - jak vymazat z ArrayListu množinu položek
« Odpověď #28 kdy: 23. 09. 2019, 13:12:40 »
Metoda ArrayList.removeAll() provadi remove v cyklu, coz zvysuje vypocetni slozitost.

removeAll hlavně dělá něco jiného, než na co se ptal tazatel. Odstraňuje položky podle hodnot, on chce odstranit podle indexů.

To je samozrejme pravda, ale vase pozorovani neni v rozporu s tim, co jsem napsal.

Re:Java - jak vymazat z ArrayListu množinu položek
« Odpověď #29 kdy: 23. 09. 2019, 13:49:18 »
Algoritmu, ktery jsem uvedl v prispevku, je maximalne efektivni
Je dost odvážné tvrdit o něčem, že je to maximálně efektivní, když neznáte přesné zadání. Váš algoritmus ponechá původní velikost podkladového pole, takže není paměťově efektivní. Kdybyste to chtěl spravit zavoláním trimToSize(), bude zase výpočetně neefektivní (nevíte, zda to zmenšení pole není zbytečné).

Presne zadani jsem ocekaval v prvnim prispevku tohoto fora.

Ponechava puvodni velikost podkladoveho pole a povazuji to za dobrou vlastnost. To z toho duvodu, ze 1) pro jakoukoliv dalsi naslednou operaci, ktera ma za nasledek zmenu velikosti listu neni rozumne toto provadet automaticky a 2) mame onu metodu trimToSize, ktera toto dela na vyzadani. To, ze tam nejake pole je, je vlastnosti ArrayListu a je treba s tim pracovat. Nasledna prace se zmenou velikosti pole nebyla pozadovana.

Dovoluji si tvrdit, ze to je maximalne efektivni algoritmus proto, ze pouziva pouze pristup do 2 poli pres index a jeho narocnost neni vyssi nez narocnost jednoho pruchodu podkladoveho pole. Pokud nemam pravdu, tak by to chtelo necim konkretnim dolozit (efektivnejsim algoritmem, at to neni pouze akademicka debata).
Dalsi uvadene zpusoby zalozene na kopirovani (neodstranuje elementy a dopredu nevime jako bude mit vysledny list velikost, pouze ze bude mensi nebo stejne velky - opet skryte kopirovani pole pri rustu velikosti vysledneho listu) nebo odstranovani prvku z puvodniho listu (volanim metody remove) jsou mene efektivni. Odstranovani pro kazde volani posouva zbytek pole za odstranenym elementem. To je nevyhoda ArrayListu. Je to wrapper nad polem, ktery dela presne to, co ma delat a jeho vlastnosti plynou uz ze jmena teto struktury *Array*List.