Avatar billede dennism Nybegynder
25. september 2006 - 18:29 Der er 33 kommentarer og
2 løsninger

Java: Hjælp til datastrømme?

Jeg har fået en programmeringsopgave, som jeg har tænkt mig at lave i Java.
Tag først et kig på denne .cvs-fil (åben den venligst i notepad el. lign):
http://www.demaweb.dk/java.cvs

Som I kan se, så indeholder den 6 liner. Hver linie er adskilt af ; således at hver linie danner 16 kolonner.

Jeg vil gerne kunne trække disse data ud, således at jeg får et 2D-array a[i][j], hvor i er linienummer og j er kolonne.

Med andre ord; er der nogen der kan hjælpe mig med at lave et lille program som tager denne fil som input og udfra dette input opstiller met array.
Programmet kunne så passende returnere a[2][1] som gerne skulle være "AN".

Håber der er en, som kan hjælpe mig med dette. Jeg har desværre ikke flere point :(
Avatar billede dennism Nybegynder
25. september 2006 - 18:29 #1
Avatar billede dennism Nybegynder
25. september 2006 - 19:47 #2
Som I ser, så er den første linie:
  ;Mandag;;;Tirsdag;;;Onsdag;;;Torsdag;;;Fredag;;

Jeg har nu lavet en kode, som indhenter denne i Stringen line.

Jeg kører derefter:
            StringTokenizer separator = new StringTokenizer(line, ";");
           
            while (separator.hasMoreTokens())  {
                String text = separator.nextToken();
                System.out.println(text);
            }

problemet er så bare, at det returnerer:
�
Mandag
Tirsdag
Onsdag
Torsdag
Fredag

Her er problemet, at jeg også gerne vil have at den opdager når der ikke er noget tekst mellem ;'erne :(

Kan I hjælpe med dette?
Avatar billede mikkelbm Nybegynder
25. september 2006 - 19:59 #3
Prøv i stedet:

String text = ";Mandag;;;Tirsdag;;;Onsdag;;;Torsdag;;;Fredag;;";
String[] splitted = text.split(";");
       
for (int i = 0; i<splitted.length; i++)
    System.out.println (splitted[i]);
Avatar billede dennism Nybegynder
25. september 2006 - 20:07 #4
Tak, så er jeg næsten ved at være i mål.

I starten laver jeg denne String-array til at indeholde alle data:
String in[][] = new String[10][16];

Det kræves, at jeg fra start ved hvor mange linier filen indeholder og hvor mange ; der er i den linie hvor der er flest.
Den med at finde ud af, hvor mange ; der er i den linie der er flest, må kunne føres med en line.split og en for-løkke.
Men hvordan finder jeg ud af, hvor mange linier der er i filen?
Avatar billede mikkelbm Nybegynder
25. september 2006 - 20:14 #5
Jeg ville nok bruge nogle mere dynamiske lister til det formål.

Lidt pseudo-kode:

ArrayList lines = new ArrayList ();

for (hver linje i filen)
{
  ArrayList splittedValues = new ArrayList ();
  lines.add (splittedValues);
  String[] splitted = linje.split (";");
  for (hver string i splitted)
      splittedValues.add (string);
}

Nu har du så et dynamisk to-dimensionelt array.
Avatar billede mikkelbm Nybegynder
25. september 2006 - 20:16 #6
Og hvor du før lavede:

string value = values[1][2];

laver du nu:

string value = lines.get (1).get (2);
Avatar billede mikkelbm Nybegynder
25. september 2006 - 20:17 #7
Jah... Du kan så kun gøre:

String value = lines.get (1).get (2);

Hvis du gør brug af generics. Ellers er du nødt til at caste:

String value = (String)((ArrayList)lines.get (1)).get (2);
Avatar billede dennism Nybegynder
25. september 2006 - 20:23 #8
Er der noget formål med at bruge det du kalder dynamiske lister? det andet fungerer da ret godt her ;)
Avatar billede dennism Nybegynder
25. september 2006 - 20:26 #9
Hvis jeg laver om til ArrayList istedet, hvordan indsætter jeg så f.eks. på plads 1,2?
Avatar billede mikkelbm Nybegynder
25. september 2006 - 20:27 #10
Formålet er at du ikke behøver kende størrelsen på dine arrays. Det var jo dit problem!
Avatar billede dennism Nybegynder
25. september 2006 - 20:33 #11
Jeg er ovre i noget ala dette:

import java.io.*;
import java.util.*;

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

        FileReader file = new FileReader("java.csv");
        BufferedReader fileIn = new BufferedReader(file);
       
        ArrayList lines = new ArrayList();
        ArrayList columns = new ArrayList();
        lines.add(columns);
       
        String line = fileIn.readLine();
       
        for (int i=0; line != null;i++) {
            String[] separator = line.split(";");
     
            for (int j = 0; j<separator.length; j++) {
                System.out.println(separator[j]);
                lines.get(i).add(j) = separator[j];
            }
   

            line = fileIn.readLine();
        }
       
//        System.out.println(lines.get(1).get(2););
               
    }
   
}


Men jeg får bare disse fejl meddelser:
/home/dennis/Java/TimetableConvert/src/TimetableConvert.java:22: cannot find symbol
symbol  : method add(int)
location: class java.lang.Object
                lines.get(i).add(j) = separator[j];
Note: /home/dennis/Java/TimetableConvert/src/TimetableConvert.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

kan du fortælle mig, hvorfor jeg får dem?
Avatar billede dennism Nybegynder
25. september 2006 - 21:39 #12
Altså..jeg har værdien af kolonnen i separator[j];.

den værdi vil jeg gerne putte ind i lines[i][j]. Hvordan gør jeg det?
Avatar billede hacked Nybegynder
26. september 2006 - 01:58 #13
Er der ikke fejl i den fil du har lagt op?
Nogle af linierne indeholder 14 ; mens andre indeholder 16 ; .

Anyway her lidt kode:

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;

public class TimeTableConvert {
   
    public TimeTableConvert() {
   
    }
   
    public void run() {
        try {
            FileReader file = new FileReader("c:\\exp\\java.csv");
            BufferedReader fileIn = new BufferedReader(file);
            ArrayList lines = new ArrayList();
            String line = fileIn.readLine();
            int counter = 0;
            while(line!=null) {
                lines.add(counter,new ArrayList());
                String[] separator = line.split(";");
                System.out.println(separator.length);
                for (int i = 0; i < separator.length; i++)  {
                    System.out.println("counter: "+counter+" i: "+i+" string: "+separator[i]);
                    ((ArrayList)lines.get(counter)).add(i,separator[i]);
                }
                line = fileIn.readLine();
                counter++;
            }
            System.out.println(((ArrayList)lines.get(2)).get(1));
        }   
        catch(Exception e) {
            e.printStackTrace();
        }
    }
   
    public static void main(String[] arqs) {
        TimeTableConvert t = new TimeTableConvert();
        t.run();
    }
}
Avatar billede hacked Nybegynder
26. september 2006 - 02:03 #14
Ps. Når du henter noget ud af en ArrayList er det altid et objekt af typen object du får tilbage. Husk derfor at typecast det til den rigtige type.
Avatar billede dennism Nybegynder
26. september 2006 - 07:00 #15
Tror næsten vi er ved at være i mål nu, har bare lidt problemer her:

import java.io.*;
import java.util.*;

public class TimetableConvert {
 
    public static void main(String args[]) {
        try {
            FileReader file = new FileReader("java.csv");
            BufferedReader fileIn = new BufferedReader(file);

            ArrayList lines = new ArrayList();
            ArrayList columns = new ArrayList();
            lines.add(columns);

            String line = fileIn.readLine();

            for (int i=0; line != null;i++) {
                String[] separator = line.split(";");

                for (int j = 0; j<separator.length; j++) {
                    ((ArrayList)lines.get(i)).add(j,separator[j]);
                }


                line = fileIn.readLine();
            }

            System.out.println(((ArrayList)lines.get(2)).get(1));
        } catch(Exception e) {
            e.printStackTrace();
        }       
    }
   
}


Den får disse compiler-fejl tilbage:
Note: /home/dennis/Java/TimetableConvert/src/TimetableConvert.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
compile:
run:
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
        at java.util.ArrayList.RangeCheck(ArrayList.java:546)
        at java.util.ArrayList.get(ArrayList.java:321)
        at TimetableConvert.main(TimetableConvert.java:21)

Håber der er nogen der kan give et bud?
Avatar billede mikkelbm Nybegynder
26. september 2006 - 08:00 #16
Det er nok fordi at du i:

((ArrayList)lines.get(i)).add(j,separator[j]);

Prøver at hente en liste ud der ikke eksisterer. Du får jo kun add'et én ArrayList til din lines-ArrayList.

Følgende:

ArrayList columns = new ArrayList();
lines.add(columns);

Skal flyttes ind i dit loop, så der for hver linje bliver add'et en ny arraylist.
Avatar billede dennism Nybegynder
26. september 2006 - 08:14 #17
Den det flyttes ind i den første eller anden for-løkke?
Avatar billede dennism Nybegynder
26. september 2006 - 08:20 #18
Anyways, det hjalp.

Men hvorfor får jeg denne bemærkning med på vejen:
Note: /home/dennis/Java/TimetableConvert/src/TimetableConvert.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Avatar billede mikkelbm Nybegynder
26. september 2006 - 08:28 #19
Det er fordi du compiler med Java 1.5 uden at bruge generics.
Avatar billede dennism Nybegynder
26. september 2006 - 08:35 #20
Hvad er generics, undskyld jeg spør? :)
Avatar billede mikkelbm Nybegynder
26. september 2006 - 08:37 #21
Generics gør at du kan typesikre dine lister.

http://java.sun.com/developer/technicalArticles/J2SE/generics/
Avatar billede dennism Nybegynder
26. september 2006 - 08:48 #22
Hvad er det så helt præcist jeg skal ændre i min kode, for få sikre typerne? ..eller skal jeg bare droppe det?
Avatar billede mikkelbm Nybegynder
26. september 2006 - 08:59 #23
Det er ikke nødvendigt at gøre det. Du slipper bare for at caste dine returværdier når du henter fra listerne.

Der er flere gode eksempler i linket.

Uden generics er du nødt til at caste til en String:

ArrayList list = new ArrayList();
list.add("Hej med dig");
String text = (String) list.get(0);


Med generics er det ikke nødvendigt at caste:

ArrayList<String> list = new ArrayList<String>();
list.add("Hej med dig");
String text = list.get(0);
Avatar billede dennism Nybegynder
26. september 2006 - 09:09 #24
import java.io.*;
import java.util.*;

public class TimetableConvert {
 
    public static void main(String args[]) {
        try {
            FileReader file = new FileReader("java.csv");
            BufferedReader fileIn = new BufferedReader(file);

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

            String line = fileIn.readLine();

            for (int i=0; line != null;i++) {
                ArrayList<String> columns = new ArrayList<String>();
                lines.add(columns);
                String[] separator = line.split(";");

                for (int j = 0; j<separator.length; j++) {
                    ((ArrayList)lines.get(i)).add(j,separator[j]);
                }


                line = fileIn.readLine();
            }

            System.out.println(((ArrayList)lines.get(2)).get(1));
        } catch(Exception e) {
            e.printStackTrace();
            System.out.println("Der skete en fejl.");
        }       
    }
   
}

Hvorfor vil den ikke ædde overstående? Kender godt til Generics, efter jeg så dit eksempel - vidste bare ikke, at det her det :)

Jeg får disse compiler fejl:


/home/dennis/Java/TimetableConvert/src/TimetableConvert.java:17: cannot find symbol
symbol  : method add(java.util.ArrayList<java.lang.String>)
location: class java.util.ArrayList<java.lang.String>
                lines.add(columns);
/home/dennis/Java/TimetableConvert/src/TimetableConvert.java:21: inconvertible types
found  : java.lang.String
required: java.util.ArrayList
                    ((ArrayList)lines.get(i)).add(j,separator[j]);
/home/dennis/Java/TimetableConvert/src/TimetableConvert.java:28: inconvertible types
found  : java.lang.String
required: java.util.ArrayList
            System.out.println(((ArrayList)lines.get(2)).get(1));
3 errors
Avatar billede mikkelbm Nybegynder
26. september 2006 - 09:33 #25
ArrayList<String> lines = new ArrayList<String>();

skal ændres til:

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

burde kunne gøre det...
Avatar billede dennism Nybegynder
26. september 2006 - 09:38 #26
Det er nu gjort, men får stadig samme bemærkning af compileren:

Note: /home/dennis/Java/TimetableConvert/src/TimetableConvert.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Avatar billede dennism Nybegynder
26. september 2006 - 09:38 #27
Vil du se den samlede kode?
Avatar billede dennism Nybegynder
26. september 2006 - 11:18 #28
Skal der ikke ændres i
    ((ArrayList)lines.get(i)).add(j,separator[j]);
eller
    System.out.println(((ArrayList)lines.get(2)).get(1));

efter vi har lavet generics?
Avatar billede dennism Nybegynder
26. september 2006 - 14:21 #29
Jeg har dette, som kører fint og for inden mærkelige bemærkninger:

import java.io.*;
import java.util.*;

public class TimetableConvert {
 
    public static void main(String args[]) {
        try {
            FileReader file = new FileReader("java.csv");
            BufferedReader fileIn = new BufferedReader(file);
           
            ArrayList<ArrayList<String>> lines = new ArrayList<ArrayList<String>>();

            String line = fileIn.readLine();

            for (int i=0; line != null;i++) {
                ArrayList<String> columns = new ArrayList<String>();
                lines.add(columns);
                String[] separator = line.split(";");

                for (int j = 0; j<separator.length; j++) {
                    lines.get(i).add(j,separator[j]);
                }


                line = fileIn.readLine();
            }

            System.out.println(lines.get(2).get(1));
        } catch(Exception e) {
            e.printStackTrace();
            System.out.println("Der skete en fejl.");
        }       
    }
   
}


Er jeg I mål? :)
Avatar billede hacked Nybegynder
26. september 2006 - 14:30 #30
Ja - Du kan eventuelt sammenligne med 26/09-2006 01:58:11. Eneste forskel er din brug af generics og forløkken istedet for whileløkken.
Avatar billede dennism Nybegynder
26. september 2006 - 14:41 #31
Ok, tak ;)
Må jeg be om et svar fra jer?
Avatar billede hacked Nybegynder
26. september 2006 - 22:38 #32
Svar.
Avatar billede mikkelbm Nybegynder
26. september 2006 - 22:56 #33
.
Avatar billede dennism Nybegynder
27. september 2006 - 08:40 #34
Tak for hjælpen :)

Kan I iøvrigt forklare, hvorfor der er forskel på specieltegn når jeg bruger enten Windows eller Linux? Jeg lavede et program i Linux, men da jeg flyttede det over på min Windows maskine, var alle specialtegn ødelagt.
Avatar billede dennism Nybegynder
02. oktober 2006 - 22:09 #35
Evt. en der kan hjælpe her:
http://www.eksperten.dk/spm/736084
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