Avatar billede hono Nybegynder
14. februar 2005 - 21:23 Der er 16 kommentarer og
2 løsninger

Array med ukendt størrelse

Jeg er lige begyndt at lege med java, og er i den forbindelse løbet ind i et problem vedrørende arrays. Jeg har fundet ud af at man er nødt til at angive sit arrays størrelse når man opretter det. Men det er jo langt fra altid man ved hvor mange elementer der skal være plads til i arrayet.

Jeg har fx lavet et program der læser fra en txt-fil, og finder middelværdien af de tal filen indeholder. Før filen genkender tallene, skal de stå på en linie for sig. Anden form for data, fx tekst, ignoreres. Jeg vil dog gerne gemme alle forekomster af ugyldigdata i et array. Således kan jeg efter følgende udskrive en fajlmeddelelse a la: "Følgende data kunne ikke betragtes som tal:..." og så alle arrayelementerne. Men da jeg ikke ved hvor meget udgyldigt data min fil vil indeholde, kan jeg ikke på forhånd vide hvor stort arrayet skal være.

Hvordan håndterer man sådan en situation i java?

På forhånd tak

Hono
Avatar billede hono Nybegynder
14. februar 2005 - 21:25 #1
fajlmeddelelse = fejlmeddelelse
Avatar billede mikkelbm Nybegynder
14. februar 2005 - 21:25 #2
Brug en ArrayList, Vector, LinkedList

Ligger i java.util
Avatar billede tigertool Nybegynder
14. februar 2005 - 21:25 #3
ArrayList eller Vector?
Avatar billede snoop_one Nybegynder
14. februar 2005 - 21:27 #4
Du skal nok kigge på collections frameworket. Du kan evt. benytte et ArrayList.
Avatar billede mikkelbm Nybegynder
14. februar 2005 - 21:27 #5
ArrayList list = new ArrayList();

while (..betingelse..)
{
  list.add (et_eller_andet);
}
Avatar billede snoop_one Nybegynder
14. februar 2005 - 21:28 #6
Avatar billede hono Nybegynder
14. februar 2005 - 21:29 #7
Jeg er som sagt lige begyndt at programmere java, så jeg skal nok have det skåret lidt mere ud i pap. Har i evt et link til en side hvor ArrayList-Klassen beskrives i detaljer?
Avatar billede hono Nybegynder
14. februar 2005 - 21:29 #8
tak, kigger på det
Avatar billede tigertool Nybegynder
14. februar 2005 - 21:30 #9
Lidt info om Vector:

import java.util.Vector;

...

Vector minVector = new Vector();

Tilføj: minVector.add("hej");

Hent: minVector.elementAt(0);

Hent alle:
for (int i = 0; i < minVector.size(); i++)
{
  minVector.elementAt(i);
  // gør noget med det.
}

Tjek selv om det virker :) Har ikke lige nogen compiler her.
Avatar billede hono Nybegynder
14. februar 2005 - 21:42 #10
Jeg har fået det til at virke med ArrayList. Men jeg får følgende advarsel når jeg kompilerer:

Note: C:\Documents and Settings\...\Program.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

Det skal dog siges at den kompileres korrekt, og programmet kører efter hensigten. Men hvad skyldes advarslen og hvad kan/bør jeg gøre ved det?
Avatar billede mikkelbm Nybegynder
14. februar 2005 - 21:44 #11
Og det er først kommet efter brug af ArrayList?

I så fald, prøv at poste hvad du gør der.
Avatar billede snoop_one Nybegynder
14. februar 2005 - 21:44 #12
Her er et lille eksempel:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

public class TestReader {

    public static void main(String[] args) {
        new TestReader(TestReader.class.getResource("testFile.txt").getFile());
    }

    public TestReader(String filename) {
        ArrayList notNumbers = new ArrayList();
        double sum = 0;
        int count = 0;
        try {
            BufferedReader in = new BufferedReader(new FileReader(filename));
            String str;
            while ((str = in.readLine()) != null) {
                try {
                    sum += Double.parseDouble(str);
                    count++;
                } catch (NumberFormatException e) {
                    notNumbers.add(str);
                }
            }
            in.close();
        } catch (IOException e) {
            System.err.println("The file could not be found");
            e.printStackTrace();
        }
        System.out.println("Mean value is: "+ sum/count);
        System.out.println("The following data was omitted");
        for (Iterator iter = notNumbers.iterator(); iter.hasNext();) {
            System.out.println(iter.next());
        }
    }
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Filen testFile.txt:
5.5
5.3
7.2
a
b
c
some other stuff
8
10
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Når du køre programmet fåes følgende:
Mean value is: 7.2
The following data was omitted
a
b
c
some other stuff
Avatar billede hono Nybegynder
14. februar 2005 - 21:50 #13
Her er min fulde kode:


import java.util.Scanner;
import java.util.ArrayList;
import java.io.*;



//LAV NY RAPPORTKLASSE. SØRG FOR AT BLANKE LINIER IGNORERES. KIG PÅ ARRAYPROBLEM
//SKRIV I HVILKEN/HVILKE LINIER DER STØRSTE TAL ER. LAV WHILELØKKE SÅ PROGRAMMET
//KAN KØRES FORFRA.


public class ExternFil{

  public static void main(String[] args) throws IOException{

    /**************************************************************************
    * De nødvendige variabler oprettes. Variablerne (undtagen "koer") initiali
    * -seres først inde i den efterfølgende whileløkke, da det således sker
    * hver gang whileløkken køres!
    *************************************************************************/

    double sum, aktuelleTal, storste, middelvaerdi;
    int linie, talIalt, fejlNr;
    String filnavn, aktuelleLinie, koer = "j";
    boolean besluttet = false, gyldigFil=false;
   
    Scanner tastatur = new Scanner(System.in);
    Scanner filescan;

    while(koer.equalsIgnoreCase("j")){
     

            //Initialisering

            ArrayList ugyldigData = new ArrayList();
            sum = 0;
            storste = 0;
            linie = 0;
            talIalt = 0;
            filescan = new Scanner("");
           


            System.out.print("Indtast filnavn: ");
           
            do{           
           
                try{
           
                      filnavn = tastatur.nextLine();
               
          //Lav noget med en try, hvor det forsøges at sætte at hente data
          //fra den indtastede fil. Mislykkes det, skal der være en catch
          //der sender én tilbage igen.
               
                      filescan = new Scanner(new File(filnavn));
                      gyldigFil = true;
                 
                  }catch(FileNotFoundException exception){
                 
                      System.out.println("Den angivne fil blev ikke fundet.");
                      System.out.print("Vælg et andet filnavn: ");
                      gyldigFil = false;
                  }

           
            }while(gyldigFil==false);
           
    /***************************************************************************
    * Filens data gennemløbes. Tal indgår i beregning af middelværdi, samt søgen
    * efter største tal, mens ugyldige data (dvs. alt andet end tal), gemmes i
    * ArrayListen "ugyldigData".
    ***************************************************************************/
         
          while(filescan.hasNext()){

              linie++;
              aktuelleLinie = filescan.nextLine();

              try
              {

                //Data til udregning af middelværdi indsamles

                aktuelleTal = Double.parseDouble(aktuelleLinie);
                sum += aktuelleTal;
                talIalt++;

                    //Tjekker det aktuelle tal er det hidtil største

                    if(talIalt == 1){
                          storste = aktuelleTal; //Første tal sættes som udgangspunkt som det største
                    }else{
                          storste = (aktuelleTal > storste)? aktuelleTal : storste;
                    }


                }catch(NumberFormatException exception){  //Hvis den aktuelle linie ikke kunne konverteres til en double

                    ugyldigData.add("linie "+linie+":\t\""+aktuelleLinie+"\"");
                   
                }

            }



    /*************************************************************************
    * De beregnede resultater udskrives. Hvis ingen tal blev fundet i filen,
    * udskrives i stedet en fejlmeddelelse
    ************************************************************************/


            if(talIalt>0){  //Tjekker om der overhovedet blev fundet nogle tal

                middelvaerdi = sum/talIalt;

                  System.out.println("Sum = "+sum);
                  System.out.println("Tal ialt = "+talIalt);
                  System.out.println("Det største tal er: "+storste);
                  System.out.println("Middelværdien er: "+middelvaerdi);




    /************************************************************************
    * En statusrapport udskrives. Den indeholder information om de linier hvis
    * indhold ikke kunne konverteres til en talværdi
    ************************************************************************/


                System.out.println("\n******************************************");
                System.out.println("Statusrapport");
                System.out.println("******************************************\n");

                  System.out.println("Følgende data kunne ikke genkendes som tal:\n");

                  for(int i = 0; i < ugyldigData.size(); i++){

                          System.out.println(ugyldigData.get(i));

                  }

            }else{
               
                System.out.print("Filen indeholder ingen tal.");
                System.out.println("Bemærk at kun linier indeholdende udelukkende ét tal, genkendes som et gyldigt tal");
            }
       
       

    /***************************************************************************
    * Programmet er nu afviklet og brugeren får valget mellem at starte forfra
    * (ved at trykke "j" hvorved whileløkken gentages) eller at afslutte
    * (ved at trykke "n")
    ***************************************************************************/
       
            do{
                       
                System.out.println("\n\nØnsker du at køre programmet igen? J/N");
           
                koer = tastatur.nextLine();
           
                if(koer.equalsIgnoreCase("j")||koer.equalsIgnoreCase("n")){
               
                    besluttet=true;
               
                }else{ //Brugeren tastede hverken "j" eller "n". Do-løkken skal gentages
                   
                    besluttet=false;   
                }
               
            }while(besluttet==false);
           

    } //Slut på den store while(koer.equals...)-løkke
  }
}
Avatar billede mikkelbm Nybegynder
14. februar 2005 - 21:58 #14
Den fejl du får er i forbindelse med linjen:

ugyldigData.add("linie "+linie+":\t\""+aktuelleLinie+"\"");

Det eneste den fortæller dig er, at der i den nye Java 1.5 er generics hvor du kan typebestemme en ArrayList.

F.eks. hvis du ved der KUN må komme strings i din ArrayList kan du gøre følgende:

ArrayList<String> ugyldigData = new ArrayList<String>();

På den måde får du compilerfejl hvis du prøver at adde andet end strings.

Det gør man ikke hvis ikke man gør brug af generics.
Avatar billede mikkelbm Nybegynder
14. februar 2005 - 21:59 #15
Uden brug af generics kan man komme alle typer objekter i en ArrayList. Hvis man så kommer forskellige typer i, og prøver at hente dem ud og caste dem, vil man få en runtimeexception.
Avatar billede hono Nybegynder
14. februar 2005 - 22:05 #16
Perfekt mikkelbm. Jeg siger mange tak for hjælpen

Snoop one og tigertool >> I må lige smide et svar hvis I skal have del i pointene.
Avatar billede tigertool Nybegynder
14. februar 2005 - 22:06 #17
svar
Avatar billede snoop_one Nybegynder
15. februar 2005 - 00:26 #18
kan ikke smide et svar når du har accepteret...
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