Som i kan se laver jeg en list(vector) om til et string array, men når jeg så vil tilgå dette array virker det ikke! det virker som om at det kommer ud af scope.
kan man ikke allokere et string array dynamisk og så f.eks initalisere en klasse med dette array i constructoren.
Det den skal er faktisk at hente data fra min database og putte det hele ind i en listbox.
Denne side indeholder artikler med forskellige perspektiver på Identity & Access Management i private og offentlige organisationer. Artiklerne behandler aktuelle IAM-emner og leveres af producenter, rådgivere og implementeringspartnere.
hmmm.... Det kan jeg ikke forstå. Er det fuldstændigt umuligt at allokere et String array fra en vector ? items = (String[])res.toArray(new String[i]); Denne linie "mener" jeg konvertere list elementet om til et String element, men der er måske noget jeg har taget fejl.
Jeg er muligvis meget træt, men er det dette, som du mener: ... Vector v = new Vector(33); String item[] = new String [33]; item = (String[]) v.toArray(); osv..
Her smides Vector elementerne over i et String Array.
Hvis det er helt hen i vejret, så bær over med mig, for jeg er meget træt*g*
Det du skal gøre er (jeg har tilladt mig at fjerne koden med x-variablen)
String[] items; if (res != null && res.size() > 0) { items = new String[res.size()];
/// HERFRA OG TIL NÆSTE KOMM. KUN NØDVENDIG, HVIS INDHOLD SKAL UDSKRIVES for (int i = 0; i < res.size(); i++) { System.out.println(res.elementAt(i)); } //////////////////////////////////////////////////////////////////////// res.toArray(items); } System.out.println(items[]);
Læg mærke til at parameter til toArray metoden ikke bare er hvilken som helst initialiseret array, men faktisk den array, som indholdet skal kopieres over i...
( og det finder man hurtig ud af, hvis man lige læser API'en )
public Object[] toArray(Object[] a)
Parameters: a - the array into which the elements of the Vector are to be stored, if it is big enough; otherwise, a new array of the same runtime type is allocated for this purpose.
havmaage: Hmmm, det virker lidt mærkeligt at du ikke brød dig om min løsning. bearhugx løsning er endda længere end min løsning. Er der nogen speciel grund til din pointfordeling?
carstenknudsen... Kunne det tænkes at din løsning ikke virker :-/ ...
Dit svar << items = (String[])res.toArray(new String[0]); >> vil ikke virke, da du putter alle resultaterne i den anonyme array (new String[0]) ... Og da du ikke tildeler en variabel til den, forbliver den anonym indenfor selve kaldets scope... Hvad der sker umiddelbart efter kaldet er færdigt, er at den nye array (og de rigtige værdier) ryger direkte på garbage collectorens heap..
bearhugx: det er testet og virker, du har måske ikke læst dokumentationen du selv har kopieret ind tsk tsk. Hvis du giver en array der ikke har plads nok i den (brug altid en array af længde 0 her) vil den returnere en array af samme type: "otherwise, a new array of the same runtime type is allocated for this purpose". Det forklarer ikke dispositionen, men måske er der en, det er den jeg søger. Din fine forklaring med heap'en den kan vi lægge direkte på, tja heap'en :)
Hej carstenknudsen>> Det er bestemt ikke fordi jeg ikke vil give dig point også, jeg er meget glad for at få forskelligt input, men det kan til tider være svært at gennemskue hvad der er "den bedste måde" når man er så ny i det her som jeg er. Jeg fandt faktisk selv en løsning, som er lidt forskelligt fra den i forslår.
Vector res = new Vector(); res = ac.doQuery("SELECT fornavn FROM person"); String[] items = new String[10]; if (res != null && res.size() > 0) {
for (int i = 0; i < res.size(); i++) {
items = (String[])res.toArray(new String[i]);
}
}
for (int i = 0; i < items.length; i++) { System.out.println(items[i].toLowerCase()); }
Der ryger arrayet bare i en loop ved udskrivning til stdout, jeg vil lige prøve jeres forslag af, og har jeg gjort nogen til skamme opretter jeg et nyt spørgsmål således at tingende er fair.
havmaage: den løsning du præsenterer den bliver du nødt til at smide væk, den er et udemærket forsøg, men den er meget ineffektiv. Hvis du har N strenge i den får du kopieret N*(N-1)/2. Det er rigtig mange når du har N stor. Ved 100 strenge hvor du skulle kopiere 100 strenge kopierer du 450, og det bliver værre for større N. Det er fint at du fandt din egen løsning, men du skal erstatte den med de tre linier jeg smed op, det er den korteste og hurtigste formulering du kan få. Du skal selvfølgelig ikke oprette et nyt spørgsmål, jeg klarer mig, men hvis du sletter de tomme linier og kommentarer i bearhugx (udemærkede svar) så finder du at de er næsten identiske. Det vigtigste lige nu er at du ser på din egen løsning og forstår hvorfor den er farlig. Du kører løkken i gennem N gange og hver gang kopierer du henholdvis 1,2,3,...,N strenge, og det er i længden dyrt. Du kan evt. prøve at time forskellen med f.eks. 10000 strenge, så bliver du nok overrasket. God kodning!
Cartsen! mange tak for dit input har jeg forstået det rigtigt hvis jeg tror at problemet med min løsning er her (new String[i]); hvor i incrementeres og derved bliver i antal kopieret = i gange altså ved 28 strenge udføres det jo således items = (String[])res.toArray(new String[38]); ??
Du gør følgende: når i er 0 opretter du en String[0] når i er 1 opretter du en String[1] ..... når i er 8 opretter du en String[8] ... når i er N-1 opretter du en String[N-1] Det bliver rigtig mange når du i virkelighen kun har brug for en enkelt String[N]. Den sidste (String[N]) bliver faktisk aldrig oprettet, så dit sidste element i vektoren kommer aldrig ud, hvad der kan være ganske alvorligt, alt efter hvad du laver; det er i hvertfald uheldigt ikke at få alle dine resultater ud fra databasen.
carstenknudsen >> Undskyld min bestyrtelse ang. dit svar... Har lige afprøvet det igen, og har "opdaget" at din metode faktisk virker...
....Sorry :-).... (Mit testarray var dog tomt, da jeg efterprøvede din kode i eftermiddags.:-/ - måske en slåfejl eller et noget andet - jeg ved det ikke :-)
Men nu, hvor vi er på emnet omkring optimering, og "dette-tager-mere-tid-end-det-andet" så er mit spørgsmål til dig
Hvad vil være mindst ressource-krævende * en preinititaliseret array, klar til at føre strengene over i (min kode) eller * at initialisere en ny array, når det opdages, at den nuværende array ikke kan holde alle de data (din kode)
dvs. items = new String[res.size()]; res.toArray(items);
eller String[] items; items = (String[])res.toArray(new String[0]);
Jeg ved det ikke - og spørger dig...
/Søren
PS : Min kommentar omkring hvad der sker med annonyme objekter, når de ryger ud af scope (heap-fortællingen)>> det er den læredom, jeg har modtaget fra min programmeringslærer, da jeg gik på datamatiker-uddannelsen... Hvis den ikke er rigtig, skal jeg da irettesætte min lærer næste gang jeg møder ham... :-))
bearhugx: vi er jo heldigvis enige. Det er et interessant spørgsmål hvad der er mest effektivt af de to metoder. Svaret er nok at det er implementerings- afhængigt. F.eks. har det betydning hvordan size() metoden i Collection er implementeret. Vi taler jo ikke om Vector men om alle Collections (interface Collection). I en kompliceret træstruktur eller hægtet eller dobbelthægtet liste vil det måske være dyrt at beregne størrelsen (size()) idet hele collecion'en skal gennemløbes. Det undgår du hvis du giver en array med længden nul, for så ved metoden (toArray) at den skal oprette en ny array. I de tilfælde vil det være hurtigst bare at oprette et nyt array med den angivne type. Hvis du derimod har en Vector, ArrayList eller lign., de fleste implementeringer af List måske?, er det let at få size() og så ved man umiddelbart om der skal oprettes et nyt array. Jeg tror at der i tilfældet her ikke vil være den store forskel på de to angrebsvinkler, men jeg vil prøve at lave nogle tests med forskellige implementeringer af Collection, for at se om det betyder noget for nogle implementeringer. I virkeligheden tror jeg at de fleste af Java implementeringerne virker fint og hurtigt, hvorimod folks egne implementeringer ikke nødvendigvis er så snedige. Jeg skriver lidt om test resultaterne før frokost, men de skal nok tages med et gran salt idet jeg kører Linux og der jo kører andre processer samtidig. Selve arbejdet med at kopiere referencerne er ikke et stort arbejde og class castingen burde heller ikke være voldsom. En anden ting der er interessant er hvordan metoden får elementerne ud, er det via en Iterator? eller udnyttes det at hvis man har en RandomAccess (interface) struktur så bruger den get(int)? Det har naturligvis stor betydning for effektiviteten.
Ang. heap så tror jeg du har ret, men du brugte det til at forklare at kode der virkede ikke virkede, det var derfor jeg drillede lidt med det. Din heap forklaring skulle være ok, men det er ikke noget jeg ved meget om.
bearhugx: så er resultatet af en timing klar. Short code referer til minimum antal linier, Long code, det modsatte. Der er to tests, hvoraf den ene inkluderer initialisering af Collection, den anden regner ikke dette med. Jeg har kørt testene flere gange, og de er nogenlunde repræsentative. Konklusionen er at den lange code er lidt hurtigere for alle typer af Collections der er indbygget i Java. Forskellen er beskeden indenfor den usikkerhedsmargen der er, men den lange kode er som sagt konsekvent hurtigere. Det der har mest betydning er hvilken Collection man benytter, specielt hvis man inkluderer initiliseringen af Collection'en, hvilket også skal ske i ens program. Her er tallene for de fire tilfælde (koden postes nedenfor): Short code including initialization java.util.Vector : 0.246 java.util.ArrayList : 0.245 java.util.LinkedList : 0.317 java.util.HashSet : 0.575 java.util.LinkedHashSet : 0.616 java.util.TreeSet : 1.21 Long code including initialization java.util.Vector : 0.232 java.util.ArrayList : 0.228 java.util.LinkedList : 0.284 java.util.HashSet : 0.524 java.util.LinkedHashSet : 0.523 java.util.TreeSet : 1.175 Short code excluding initialization java.util.Vector : 0.06 java.util.ArrayList : 0.06 java.util.LinkedList : 0.053 java.util.HashSet : 0.125 java.util.LinkedHashSet : 0.09 java.util.TreeSet : 0.12 Long code excluding initialization java.util.Vector : 0.058 java.util.ArrayList : 0.056 java.util.LinkedList : 0.05 java.util.HashSet : 0.123 java.util.LinkedHashSet : 0.088 java.util.TreeSet : 0.119
import java.util.*; public class Timing { private static final int AVERAGING = 1000; private static final int ELEMENTS = 1000; public void time1() { Collection c = null; for (int j = 0; j < 6; j++) { long start = System.currentTimeMillis(); for (int k = 0; k < AVERAGING; k++) { switch ( j ) { case 0 : c = new Vector(); break; case 1 : c = new ArrayList(); break; case 2 : c = new LinkedList(); break; case 3 : c = new HashSet(); break; case 4 : c = new LinkedHashSet(); break; case 5 : c = new TreeSet(); break; } for (int i = 0; i < ELEMENTS; i++) { c.add( new Integer( i ) ); } Integer[] items = (Integer[])c.toArray( new Integer[ 0 ] ); } long end = System.currentTimeMillis(); System.out.println( "" + c.getClass().getName() + " : " + (( end - start ) / (double)AVERAGING) ); } } public void time2() { Collection c = null; for (int j = 0; j < 6; j++) { switch ( j ) { case 0 : c = new Vector(); break; case 1 : c = new ArrayList(); break; case 2 : c = new LinkedList(); break; case 3 : c = new HashSet(); break; case 4 : c = new LinkedHashSet(); break; case 5 : c = new TreeSet(); break; } for (int i = 0; i < ELEMENTS; i++) { c.add( new Integer( i ) ); } long start = System.currentTimeMillis(); for (int k = 0; k < AVERAGING; k++) { Integer[] items = (Integer[])c.toArray( new Integer[ 0 ] ); } long end = System.currentTimeMillis(); System.out.println( "" + c.getClass().getName() + " : " + (( end - start ) / (double)AVERAGING) ); } } public void time3() { Collection c = null; for (int j = 0; j < 6; j++) { long start = System.currentTimeMillis(); for (int k = 0; k < AVERAGING; k++) { switch ( j ) { case 0 : c = new Vector(); break; case 1 : c = new ArrayList(); break; case 2 : c = new LinkedList(); break; case 3 : c = new HashSet(); break; case 4 : c = new LinkedHashSet(); break; case 5 : c = new TreeSet(); break; } for (int i = 0; i < ELEMENTS; i++) { c.add( new Integer( i ) ); } Integer[] items = new Integer[ c.size() ]; items = (Integer[])c.toArray( items ); } long end = System.currentTimeMillis(); System.out.println( "" + c.getClass().getName() + " : " + (( end - start ) / (double)AVERAGING) ); } } public void time4() { Collection c = null; for (int j = 0; j < 6; j++) { switch ( j ) { case 0 : c = new Vector(); break; case 1 : c = new ArrayList(); break; case 2 : c = new LinkedList(); break; case 3 : c = new HashSet(); break; case 4 : c = new LinkedHashSet(); break; case 5 : c = new TreeSet(); break; } for (int i = 0; i < ELEMENTS; i++) { c.add( new Integer( i ) ); } long start = System.currentTimeMillis(); for (int k = 0; k < AVERAGING; k++) { Integer[] items = new Integer[ c.size() ]; items = (Integer[])c.toArray( items ); } long end = System.currentTimeMillis(); System.out.println( "" + c.getClass().getName() + " : " + (( end - start ) / (double)AVERAGING) ); } } public static void main( String[] args ) { Timing timing = new Timing(); System.out.println("Short code including initialization"); timing.time1(); System.out.println("Long code including initialization"); timing.time3(); System.out.println("Short code excluding initialization"); timing.time2(); System.out.println("Long code excluding initialization"); timing.time4(); } }
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.