Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[Java] Array van ArrayLists

Pagina: 1
Acties:

  • verytallman
  • Registratie: Augustus 2001
  • Laatst online: 13-11 10:23
Ik heb een array van ArrayLists en wil direct naar het laatste element kunnen gaan, maar het lukt me nu slechts vanaf de tweede ArrayList bij de laatste te komen.

Dit wordt duidelijker met wat code:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
ArrayList<ArrayList> AL1 = new ArrayList<ArrayList>(5);
ArrayList<ArrayList> AL2 = new ArrayList<ArrayList>(5);
ArrayList<String> AL3 = new ArrayList<String>(5);
        
AL3.add(0, "aap");
AL3.add(1, "noot");
AL3.add(2, "mies");
        
AL2.add(0, AL3);
AL1.add(0, AL2);

String dezeLuktWel = (String)AL2.get(0).get(0); // Geeft aap terug...

String dezeGeeftFoutmelding = (String)AL1.get(0).get(0).get(0);

De foutmelding is:
Inconvertible types: found java.lang.Object.get , required java.lang.String

Zie ik hier iets eenvoudigst over het hoofd, of kan dit gewoon niet?

[ Voor 0% gewijzigd door een moderator op 14-02-2008 14:15 . Reden: Code tags gefixed; syntax highlighting FTW \0/ ]


  • pedorus
  • Registratie: Januari 2008
  • Niet online
Ja, dan heb je meerdere cast's nodig. Maar wat dacht je van de volgende types:
Java:
1
2
3
List<? extends List<? extends List<String>>> = ...
List<? extends List<String>> = ...
List<String> = ...

(bron idee)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


  • Jaap-Jan
  • Registratie: Februari 2001
  • Laatst online: 18:44
De compiler weet niet wat voor type objecten hij kan verwachten. Hij 'weet' dat A1 objecten bevat van het type ArrayList, maar weet niet wat hij daarin kan verwachten omdat je daar (in de definitie van A1) geen type voor hebt opgegeven door middel van generics, dus dan gaat hij ervanuit dat ArrayList objecten van het type Object bevat.

Je moet dus de definitie van A1 en A2 op een zodanige manier doen, dat de compiler kan weten wat erin zit.

Voorzetje voor al2:
Java:
1
ArrayList<ArrayList<String>>

[ Voor 4% gewijzigd door Jaap-Jan op 13-02-2008 15:07 ]

| Last.fm | "Mr Bent liked counting. You could trust numbers, except perhaps for pi, but he was working on that in his spare time and it was bound to give in sooner or later." -Terry Pratchett


  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Je gebruikt generics maar half nu. Schrijf de generic types eens uit voor AL1 en AL2. Het type van AL2 is nu binnen de context van AL1 niet bekend.

[ Voor 0% gewijzigd door Herko_ter_Horst op 13-02-2008 15:07 . Reden: Spuit elf... ]

"Any sufficiently advanced technology is indistinguishable from magic."


  • verytallman
  • Registratie: Augustus 2001
  • Laatst online: 13-11 10:23
Jaap-Jan schreef op woensdag 13 februari 2008 @ 15:06:
De compiler weet niet wat voor type objecten hij kan verwachten. Hij 'weet' dat A1 objecten bevat van het type ArrayList, maar weet niet wat hij daarin kan verwachten omdat je daar (in de definitie van A1) geen type voor hebt opgegeven door middel van generics, dus dan gaat hij ervanuit dat ArrayList objecten van het type Object bevat.

Je moet dus de definitie van A1 en A2 op een zodanige manier doen, dat de compiler kan weten wat erin zit.

Voorzetje voor al2:
Java:
1
ArrayList<ArrayList<String>>
Thx ! Ik heb het werkend.

De goede code is dus
Java:
1
2
3
4
5
ArrayList<ArrayList<ArrayList<String>>> AL1 = new ArrayList<ArrayList<ArrayList<String>>>(5);
ArrayList<ArrayList<String>> AL2 = new ArrayList<ArrayList<String>>(5);
ArrayList<String> AL3 = new ArrayList<String>(5);

// De rest hetzelfde...

[ Voor 0% gewijzigd door een moderator op 14-02-2008 14:16 . Reden: Code tags gefixed; syntax highlighting FTW \0/ ]


  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Ik zou eens gaan kijken naar trees als datastructuren, nog een level dieper en het wordt wel heel smerig.

https://niels.nu


  • verytallman
  • Registratie: Augustus 2001
  • Laatst online: 13-11 10:23
Ik heb even verder lopen prutsen hiermee, en ik vraag me af waarom deze 2 regels niet werken:

code:
1
2
3
(String)AL1.get(0).get(0).get(1).concat("a");

(String)AL1.get(0).get(0).get(1) = "eef";



@Hydra, dit probleem is niet zozeer hoe mijn programma wil schrijven, maar meer dat ik precies wil weten hoe dit werkt.

  • Jaap-Jan
  • Registratie: Februari 2001
  • Laatst online: 18:44
Die casts zijn niet nodig.

Die eerste is niet fout en werkt bij mij, dus waarschijnlijk doe jij iets fout.

Die tweede is basic Java, je kunt geen waarde toekennen aan een functie- aanroep. Daarvoor moet je de setter gebruiken en niet de getter.

Dit is trouwens wel ongelovelijke basis Java kennis, dus ik zou je wel willen adviseren om zelf íets meer moeite te doen. ;)

| Last.fm | "Mr Bent liked counting. You could trust numbers, except perhaps for pi, but he was working on that in his spare time and it was bound to give in sooner or later." -Terry Pratchett


  • Enfer
  • Registratie: Februari 2004
  • Laatst online: 10-10 13:28
Hmm, als je al een arraylist van een arraylist van een arraylist van strings moet maken, zal ik toch even goed naar je datastructuur kijken, want dit ruikt alsof het veel netter object georienteerd opgelost zou kunnen worden ;)

( Maar dat is niet heel goed te beoordelen, aangezien we weinig informatie hebben )..

Ah, las net pas dat je wilt weten hoe het werkt :+

Ook vraag ik me af als je van te voren al weer dat je arraylist 5 items mag bevatten, waarom je niet gewoon een 'doodgewone' array pakt? Dat is iets sneller/doeltreffender imho.. ;)

[ Voor 5% gewijzigd door Enfer op 13-02-2008 20:29 ]


Verwijderd

Wat volgens mij écht afgeleerd moet worden, is om een compleet type te gebruiken om aan te duiden wat voor soort object een bepaalde property is. Bijvoorbeeld:

Java:
1
ArrayList<String> AL3 = new ArrayList<String>(5);

Wat ik daar liever zie is het volgende:
code:
1
List<String> AL3 = new ArrayList<String>(5);

Een method een List<String> laten returnen is wat mij betreft ook veel netter. Zo kun je veel eenvoudiger van implementatie wijzigen, en breek je niet teveel andere code. Die interfaces zijn er niet voor niets. Als het om functionaliteit gaat, en niet om implementatie, gebruik dan altijd interfaces of anders abstracte classes. Zie Pedorus.

  • Mammon
  • Registratie: December 2006
  • Laatst online: 05-11 15:25
Enfer schreef op woensdag 13 februari 2008 @ 20:29:Ook vraag ik me af als je van te voren al weer dat je arraylist 5 items mag bevatten, waarom je niet gewoon een 'doodgewone' array pakt? Dat is iets sneller/doeltreffender imho.. ;)
ArrayList(int initialCapacity) Constructs an empty list with the specified initial capacity.

  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 20-11 09:31
Verwijderd schreef op woensdag 13 februari 2008 @ 21:09:

Als het om functionaliteit gaat, en niet om implementatie, gebruik dan altijd interfaces of anders abstracte classes. Zie Pedorus.
Volgens mij is dat een good practice die bij vrijwel iedereen bekend is ook zo veel mogelijk wordt nagestreefd. Zeker gezien dependency injection vrij populair is en frameworks/containers daaromtrent (Spring, PicoContainer, Guice etc.) erg veel gebruikt worden.

  • Enfer
  • Registratie: Februari 2004
  • Laatst online: 10-10 13:28
Zelf een simpele klasse maken met een array met die capacity, en een array end, scheelt wel weer geheugenverbruik he, en scheelt in performance.. arrays zijn veel sneller ( instant acces ), dan ArrayLists ;)

  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 20-11 09:31
Enfer schreef op donderdag 14 februari 2008 @ 12:49:
[...]


Zelf een simpele klasse maken met een array met die capacity, en een array end, scheelt wel weer geheugenverbruik he, en scheelt in performance.. arrays zijn veel sneller ( instant acces ), dan ArrayLists ;)
De List interface biedt ook directe toegang via de index van de onderliggende array en een ArrayList verschilt qua performance zo goed als niet van een basic array.
Je eigen collection types implementeren loont volgens mij zo goed als nooit.

  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Enfer schreef op donderdag 14 februari 2008 @ 12:49:
Zelf een simpele klasse maken met een array met die capacity, en een array end, scheelt wel weer geheugenverbruik he, en scheelt in performance.. arrays zijn veel sneller ( instant acces ), dan ArrayLists ;)
Kun je dat onderbouwen ook? Aangezien arraylists ook gebruik maken van arrays, zal het verschil niet significant zijn. Tuurlijk is het wat sneller, maar dit zijn onzinnige optimalisaties die tenkoste gaan van de kwaliteit van je code.

Edit testje gedaan:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
    public static void main(String[] args)
    {
        int i, j;
        long start, stop;
        List<String> list = new ArrayList<String>(1000);
        String[] array = new String[1000];
        
        for(i = 0;i < 1000;i++)
        {
            list.add(null);
        }
        
        start = System.currentTimeMillis();        
        
        for(i = 0;i < 10000;i++)
        {
            for(j = 0;j < 1000;j++)
            {
                list.set(j, null);
                list.set(j, "Test string");
            }
        }
        
        stop = System.currentTimeMillis();
        
        System.out.println("List test: " + (stop - start) + "ms.");
        
        start = System.currentTimeMillis();
        
        for(i = 0;i < 10000;i++)
        {
            for(j = 0;j < 1000;j++)
            {
                array[j] = null;
                array[j] = "Test string";
            }
        }
        
        stop = System.currentTimeMillis();    
        
        System.out.println("Array test: " + (stop - start) + "ms.");        
    }


List 304ms, array 45ms. Op 10000*1000*2 set operaties vind ik dit niet significant.

[ Voor 52% gewijzigd door Hydra op 14-02-2008 14:45 ]

https://niels.nu


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 20-11 09:31
Precies.
Ik heb zelf ook wat testen gedraaid en ik ben totaal niet onder de indruk van het verschil in snelheid (wat pas zichtbaar wordt bij heel veel data / access). Een aantal milliseconden vind ik niet schokkend.

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Enfer schreef op donderdag 14 februari 2008 @ 12:49:
Zelf een simpele klasse maken met een array met die capacity, en een array end, scheelt wel weer geheugenverbruik he, en scheelt in performance.. arrays zijn veel sneller ( instant acces ), dan ArrayLists ;)
Ga gewoon assembler programmeren, dat is nog veel sneller.

Wie trösten wir uns, die Mörder aller Mörder?


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:59

Janoz

Moderator Devschuur®

!litemod

Als je naar de sourcecode van ArrayList kijkt
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
    /**
     * Returns the element at the specified position in this list.
     *
     * @param  index index of element to return.
     * @return the element at the specified position in this list.
     * @throws    IndexOutOfBoundsException if index is out of range <tt>(index
     *        &lt; 0 || index &gt;= size())</tt>.
     */
    public Object get(int index) {
    RangeCheck(index);

    return elementData[index];
    }



dan zie je dat het enige verschil een rangecheck is.

Java:
1
2
3
4
5
6
7
8
9
10
11
    /**
     * Check if the given index is in range.  If not, throw an appropriate
     * runtime exception.  This method does *not* check if the index is
     * negative: It is always used immediately prior to an array access,
     * which throws an ArrayIndexOutOfBoundsException if index is negative.
     */
    private void RangeCheck(int index) {
    if (index >= size)
        throw new IndexOutOfBoundsException(
        "Index: "+index+", Size: "+size);
    }

RangeCheck is verder absoluut niet spannend. Het enige verschil is dus deze ene test plus wat extra geneuzel op de stack vanwege wat extra aanroepen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • verytallman
  • Registratie: Augustus 2001
  • Laatst online: 13-11 10:23
Nog een aanvullende vraag, wanneer ik in de ArrayList AL3 meerdere type objecten wil zetten, zou ik dat zou doen:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
ArrayList<ArrayList<ArrayList<Object>>> AL1 = new ArrayList<ArrayList<ArrayList<Object>>>(5);
ArrayList<ArrayList<Object>> AL2 = new ArrayList<ArrayList<Object>>(5);
ArrayList<Object> AL3 = new ArrayList<Object>(5);

AL3.add(0, "aap");
// Andere type kun je hier nog toevoegen....

AL2.add(0, AL3);
AL1.add(0, AL2);

// Nu werkt dit niet meer:
(String)AL1.get(0).get(0).get(0).concat("a");


Dit werkt dus niet.

  • user109731
  • Registratie: Maart 2004
  • Niet online
verytallman schreef op donderdag 14 februari 2008 @ 20:58:
Nog een aanvullende vraag, wanneer ik in de ArrayList AL3 meerdere type objecten wil zetten, zou ik dat zou doen:

Dit werkt dus niet.
De compiler ziet simpelweg een "ArrayList met Object's", en Object heeft geen .Concat method. Probeer eens de haakjes anders te zetten:
Java:
1
((String)(AL1.get(0).get(0).get(0))).concat("a");

Dit werkt misschien, maar het gebruiken van generics heeft denk ik weinig nut zo. Er is vast een mooiere oplossing te bedenken dan het mixen van verschillende soorten objecten in 1 list? :)

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 17:54

Haan

dotnetter

Die code is sowieso tenenkrommend om te zien, ga dat maar eens uitleggen aan iemand anders wat je aan het doen bent.. dat moet echt veel eenvoudiger kunnen hoor ;)

Kater? Eerst water, de rest komt later


  • paulh
  • Registratie: Juli 1999
  • Laatst online: 10-11 10:50
Behalve dat de code inderdaad niet zo heel lekker is hier nog een tip:

Een String is immutable (niet wijzigbaar). Dus als je een String.concat() aanroept
zul je het resultaat weer aan dezelfde variable moeten toekennen als je wilt dat die
wijzigt. Dus x = x.concat("a");

En dat geldt dus voor alle methodes van String (replace, replaceAll, etc... ).

[ZwareMetalen.com] - [Kom in aktie tegen de CO2 maffia]


  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
JanDM schreef op donderdag 14 februari 2008 @ 21:04:
Dit werkt misschien, maar het gebruiken van generics heeft denk ik weinig nut zo. Er is vast een mooiere oplossing te bedenken dan het mixen van verschillende soorten objecten in 1 list? :)
Als je verschillende typen wilt gebruiken, gebruik je juist geen generics. Dan gebruik je een normale arraylist.

En in jouw geval moet je een boomstructuur maken, dit is echt lelijk.

https://niels.nu


  • Enfer
  • Registratie: Februari 2004
  • Laatst online: 10-10 13:28
FallenAngel666 schreef op donderdag 14 februari 2008 @ 14:14:
[...]


De List interface biedt ook directe toegang via de index van de onderliggende array en een ArrayList verschilt qua performance zo goed als niet van een basic array.
Je eigen collection types implementeren loont volgens mij zo goed als nooit.
Oh sorry ik was in de war met wat ik nu op school geleerd heb, daar gaat het met betrekking tot sorteren, en daar word ons aangeleerd arrays te gebruiken

  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Enfer schreef op vrijdag 15 februari 2008 @ 11:59:
Oh sorry ik was in de war met wat ik nu op school geleerd heb, daar gaat het met betrekking tot sorteren, en daar word ons aangeleerd arrays te gebruiken
En waarom? Omdat je daar makkelijk Array.sort op uit kunt voeren? Lekkere school dan.

https://niels.nu


  • Enfer
  • Registratie: Februari 2004
  • Laatst online: 10-10 13:28
Nee op school hebben wij geleerd hoe je dmv arrays makkelijk bijvoorbeeld een heapsort/insertion sort /*sort kunt uitvoeren ;)

Verwijderd

Over dergelijke performancewinsten zou ik m'n energie niet aan verspillen. Als je het handiger vind bepaalde functie op een array uit te voeren kun je altijd Collections.toArray() oid aanroepen. Gelukkig hoef je over het sorteren in java ook niet na te denken. Je kunt je beter bezig houden met hoe je het aantal databasecalls kunt terugdringen dan dat je je sorteeralgoritme met 5us versnelt.

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 22:35

Creepy

Tactical Espionage Splatterer

No offence maar wil je aub Programming Beleid - De Quickstart en dan met name Programming Beleid - Scriptrequests eens doorkijken? "Dit werkt niet" posten en hopen dat wij het voor je gaan fixen is dus specifiek niet de bedoeling. Het is er er nog een discussie loopt over Arrays vs ArrayLists anders het dit nu echt op slot gezeten.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 22:59

Janoz

Moderator Devschuur®

!litemod

Het is goed voor eht begrip inderdaad dat je een heapsort en insertionsort kunt doen, maar eigenlijk zou je je optimalisatie beslissingen niet op dat niveau moeten nemen. Belangrijker is om te kijken welke implementatie je gebruikt voor je lijsten. Soms is een LinkedList of TreeSet beter vanwege hoe je het gaat gebruiken. (Bij sorteren is het vaak zo dat je je gegevens altijd gesorteerd wilt houden en in dat geval is het beter om gelijk al een TreeSet te gebruiken ipv een array)

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Kwistnix
  • Registratie: Juni 2001
  • Laatst online: 20-11 09:31
Iedereen die tenminste een bachelor opleiding ICT volgt leert wel hoe datastructuren in elkaar zitten, hoe sort en search algorithmen werken en wanneer je wat moet gebruiken. Op mijn opleiding hadden we daar een module Datastructures & Algorithms, waarbij we het boek Data Structures and Algorithms in Java van Robert Lafore gebruikten. Eindeloos heb ik de code voorbeelden uit dat boek moeten lezen, overtypen en performance testen. Voor leer doeleinden prima geschikt, maar nu pak ik toch echt de implementaties uit collections framework hoor :)
Pagina: 1