Avatar billede havmaage Juniormester
23. juli 2002 - 23:09 Der er 19 kommentarer og
1 løsning

String spg igen igen, dynamisk alliokering af String Array

Hej!
Jeg har denne code stump som volder mig vanskeligheder

String[] items;
          if (res != null && res.size() > 0) {
                int x =0;
             
                for (int i = 0; i < res.size(); i++) {

                    System.out.println(res.elementAt(i));
                  // viggoe[x]=(String)res.elementAt(i);
                items = (String[])res.toArray(new String[i]);
                             
                x++;
                }
           
               

               

        }

                System.out.println(items[]); 
       


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.
Avatar billede magoo20000 Nybegynder
23. juli 2002 - 23:34 #1
ehmm.. res er et objekt af typen Vector?
Du kan godt oprette det dynamisk, hvis du ved, hvor mange elementer det skal indeholde..
Avatar billede havmaage Juniormester
23. juli 2002 - 23:39 #2
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.
Avatar billede magoo20000 Nybegynder
23. juli 2002 - 23:48 #3
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*
Avatar billede carstenknudsen Nybegynder
24. juli 2002 - 10:05 #4
Prøv at gøre sådan her:
String[] items;
if (res!= null && res.size()>0) {
items = (String[])res.toArray(new String[0]);
}
//her kan du tilgå items
Avatar billede bearhugx Nybegynder
24. juli 2002 - 11:24 #5
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...

/Søren Munk Skrøder
Avatar billede bearhugx Nybegynder
24. juli 2002 - 11:26 #6
( 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.
Avatar billede carstenknudsen Nybegynder
24. juli 2002 - 20:20 #7
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?
Avatar billede bearhugx Nybegynder
24. juli 2002 - 20:25 #8
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..
Avatar billede carstenknudsen Nybegynder
24. juli 2002 - 20:47 #9
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 :)
Avatar billede havmaage Juniormester
24. juli 2002 - 20:51 #10
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.
Avatar billede carstenknudsen Nybegynder
24. juli 2002 - 21:03 #11
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!
Avatar billede havmaage Juniormester
24. juli 2002 - 21:06 #12
Carsten! Dit forslag virkede fint, det gjore bear: også--- Så må jeg jo bare vælge...
Jeg opretter lige et spg. så får du point.
Avatar billede havmaage Juniormester
24. juli 2002 - 21:10 #13
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]); ??
Avatar billede havmaage Juniormester
24. juli 2002 - 21:11 #14
hmmm skulle have været 28 !!
Avatar billede carstenknudsen Nybegynder
24. juli 2002 - 21:16 #15
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.

Avatar billede bearhugx Nybegynder
25. juli 2002 - 00:31 #16
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... :-))
Avatar billede bearhugx Nybegynder
25. juli 2002 - 00:34 #17
PS : Hvad mener du med

<< Det forklarer ikke dispositionen, men måske er der en, det er den jeg søger. >>

i dit indlæg @ 24/07-2002 20:47:29
Avatar billede carstenknudsen Nybegynder
25. juli 2002 - 10:14 #18
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.

Dispositionen var mht point.
Avatar billede carstenknudsen Nybegynder
25. juli 2002 - 11:40 #19
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
Avatar billede carstenknudsen Nybegynder
25. juli 2002 - 11:40 #20
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();
    }
}
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester