Trädvy Permalänk
Medlem
Plats
Linköping
Registrerad
Mar 2004

Beräkna från textfil i Java

Hej!

Jag har en liten fundering som ni kanske kan hjälpa mig åt rätt håll med.

Det är så att jag har lagt in ett antal namn och åldrar i en textfil. På detta sätt;
Marie Sten
29
Alexander Lind
35
Olle Ibrahimovic
30
Kajsa Persson
35

Att spara detta och sedan läsa in är inga bekymmer. Det jag har problem med är hur jag ska kunna räkna ut medelvärdet på åldrarna?
Om jag printar ut all information så är alla strängar. Hur skulle ni gjort? Går det på något sätt att få in varannan line i en array istället för alla?
Eller kan jag på något sätt "tvinga" (stringToInt) att varannan sträng blir en int och på så sätt räkna ut det hela? Eller har ni något mer sofistikerat sätt att lösa det hela på?

Tack på förhand!

"Happiness is only real when shared"

Trädvy Permalänk
Medlem
Plats
Jönköping
Registrerad
Jul 2011

Finns väl en "funktion" som läser in alla rader till en array, sedan kan du testa att konvertera alla element i arrayen till en int med en loop. kör en try/catch och dem som lyckas läggs till i en annan array som du sedan enkelt tar medelvärdet ur.
Finns mycket bättre sätt, men var länge sedan jag höll på med java så detta är något som hade funkat i alla språk

Citera så hittar jag tillbax :D

Trädvy Permalänk
Medlem
Plats
Linköping
Registrerad
Mar 2004

Tack för svar! Det var ett liknande sätt jag tänkte på också, kommer inte alla konverteras då troligen? Tänker mer hur den känner av när alla är strängar.

"Happiness is only real when shared"

Trädvy Permalänk
Medlem
Plats
#Archlinux
Registrerad
Jun 2007

Läs in varannan rad och konvertera till double och lägg i en array som du sedan beräknar medelvärdet på.

Arch - Makepkg, not war -||- Asus Crosshair Hero VI -||- GSkill 16GiB DDR4 15-15-15-35-1T 3600Mhz -||- AMD 1600x @ 4.1GHz -||- nVidia MSI 970 Gaming -||- Samsung 850 Pro -||- EVEGA G2 750W -||- Corsair 570x -||- Asus Xonar Essence STX -||- Sennheiser HD-650 -||
Arch Linux, one hell of a distribution.

Trädvy Permalänk
Medlem
Plats
Jönköping
Registrerad
Jul 2011

Commander har ju svaret, men du sa samma sak, att läsa in varannan rad. Det du letar efter är nog att använda en streamreader. Läs på om streamreader och filer så tror jag du löser det ganska snart

Citera så hittar jag tillbax :D

Trädvy Permalänk
Medlem
Plats
Linköping
Registrerad
Mar 2004

Tack! Ville bara höra att jag var på rätt väg och inte totalt ute och cyklade.
Otroligt tacksam.

Må väl och ha en bra lördag!

"Happiness is only real when shared"

Trädvy Permalänk
Medlem
Plats
Umeå
Registrerad
Mar 2002

@sebbeharry
Att bara lagra "varannan rad som en double i en array" fungerar ju såklart för mindre saker, men det kan lätt bli grötigt och svårt att förstå om man utökar koden.
Ex. om nästa problem du försökte lösa skulle vara "Skriv ut namn och ålder på den person som är äldst resp. den person som är yngst", genom att ovanstående lösning inte bevarar namn<=>ålder associeringen så måste du ju då skriva om allt från grunden..

Skulle nog säga att du istället bör skapa en Person-klass som kan lagra namn+ålder, sen skapa ett sådant Person-objekt för varje person i filen. Detta gör att namn och ålder hör ihop, och ger även en bra grund att utgå ifrån ifall du ex. skulle haft fler attribut i filen (ex. längd).

Nått sånt här dvs:

import java.io.*; import java.util.*; class Main { public static class Person { public final String name; public final int age; public Person(String name,int age) { this.name=name; this.age=age; } //Parse from Reader public static Person fromReader(BufferedReader r) throws IOException { String name = r.readLine(); String age = r.readLine(); if(name==null || age==null){ return null; } return new Person(name,new Integer(age)); } } public static void main(String args[]) { ArrayList<Person> persons = new ArrayList<Person>(); //Read from file try { BufferedReader reader = new BufferedReader(new FileReader("persons.txt")); Person p; do { p = Person.fromReader(reader); if(p!=null){ persons.add(p); } } while(p!=null); } catch(Exception e) { System.err.println("Could not read people file: "+e.getMessage()); System.exit(1); } //Check age-thingy here int sumAge=0; for(Person p : persons) { sumAge+=p.age; } System.out.format("Avg age is %d\n", sumAge/persons.size()); } }

Dold text

The difference between stupidity and genius - the latter has limits

Trädvy Permalänk
Medlem
Plats
Linköping
Registrerad
Mar 2004

Gjorde faktiskt så från början, men sen tänkte jag att "uppgiften" inte var svårare än så och att jag troligtvis inte skulle utöka koden så då tänkte jag på den simplare lösningen.

Jag håller helt klart med dig, genom att göra ett person-objekt med både namn och ålder så blir det lättare framöver. Tack för input, ska testa båda och se hur det blir!

"Happiness is only real when shared"

Trädvy Permalänk
Medlem
Plats
Linköping
Registrerad
Mar 2004

Har försökt nu ett tag och får fel när jag ska konvertera mina strängar till double.
Jag vill som sagt läsa in varannan sträng från textfilen, konvertera till en double och sedan slänga in i min ageList-array.

Ser ni något uppenbart fel jag gör?

public class Uppgift1 { /** * @param args the command line arguments */ public static void main(String[] args)throws IOException{ String thisLine; try{ File file = new File("elevinfo.txt"); file.createNewFile(); FileWriter fw = new FileWriter(file.getAbsoluteFile()); BufferedWriter bw = new BufferedWriter(fw); bw.write("Marie Sten"); bw.write(System.lineSeparator()); bw.write("29"); bw.write(System.lineSeparator()); bw.write("Alexander Lind"); bw.write(System.lineSeparator()); bw.write("35"); bw.write(System.lineSeparator()); bw.write("Olle Ibrahimovic"); bw.write(System.lineSeparator()); bw.write("30"); bw.write(System.lineSeparator()); bw.write("Kajsa Persson"); bw.write(System.lineSeparator()); bw.write("35"); bw.close(); }catch(IOException e){ e.printStackTrace(); } try{ FileReader fr = new FileReader("elevinfo.txt"); BufferedReader br = new BufferedReader(fr); while((thisLine = br.readLine()) != null){ System.out.println(thisLine); } }catch(IOException e){ e.printStackTrace(); } try{ ArrayList<Double>ageList = new ArrayList<>(); FileReader fr = new FileReader("elevinfo.txt"); BufferedReader br = new BufferedReader(fr); while((thisLine = br.readLine()) != null){ br.readLine(); double age = Double.parseDouble(thisLine); ageList.add(age); } double sumAge = 0; for(double i : ageList){ sumAge +=i; System.out.println("Medelåldern på personerna i filen är: " + sumAge/ageList.size() ); } }catch(IOException e){ e.printStackTrace(); } } }

Dold text

Nej, jag vet att koden inte är speciellt snygg. Detta skall ändras på men nu vill jag få funktionaliteten att fungera.
Har ni några tips? Det som inte fungerar är alltså att få in åldern i arrayen.

Mvh

Edit, får nu ut något svar som absolut inte stämmer, det skrivs ut fyra gånger också men jag verkar kunna konvertera nu iaf.

while((thisLine = br.readLine()) != null){ lineNum++; if (( lineNum % 2) == 1 ){ } else{ Double age = Double.parseDouble(thisLine); ageList.add(age); } }

EDIT igen;

Haha, räknade ut innanför loopen. Tror jag ska lägga mig nu för jag är en jävla idiot. Nu funkar programmet iaf, tack för all input!

"Happiness is only real when shared"

Trädvy Permalänk
Medlem
Plats
Finland
Registrerad
Maj 2004
Skrivet av sebbeharry:

Har försökt nu ett tag och får fel när jag ska konvertera mina strängar till double.
Jag vill som sagt läsa in varannan sträng från textfilen, konvertera till en double och sedan slänga in i min ageList-array.

Ser ni något uppenbart fel jag gör?

public class Uppgift1 { /** * @param args the command line arguments */ public static void main(String[] args)throws IOException{ String thisLine; try{ File file = new File("elevinfo.txt"); file.createNewFile(); FileWriter fw = new FileWriter(file.getAbsoluteFile()); BufferedWriter bw = new BufferedWriter(fw); bw.write("Marie Sten"); bw.write(System.lineSeparator()); bw.write("29"); bw.write(System.lineSeparator()); bw.write("Alexander Lind"); bw.write(System.lineSeparator()); bw.write("35"); bw.write(System.lineSeparator()); bw.write("Olle Ibrahimovic"); bw.write(System.lineSeparator()); bw.write("30"); bw.write(System.lineSeparator()); bw.write("Kajsa Persson"); bw.write(System.lineSeparator()); bw.write("35"); bw.close(); }catch(IOException e){ e.printStackTrace(); } try{ FileReader fr = new FileReader("elevinfo.txt"); BufferedReader br = new BufferedReader(fr); while((thisLine = br.readLine()) != null){ System.out.println(thisLine); } }catch(IOException e){ e.printStackTrace(); } try{ ArrayList<Double>ageList = new ArrayList<>(); FileReader fr = new FileReader("elevinfo.txt"); BufferedReader br = new BufferedReader(fr); while((thisLine = br.readLine()) != null){ br.readLine(); double age = Double.parseDouble(thisLine); ageList.add(age); } double sumAge = 0; for(double i : ageList){ sumAge +=i; System.out.println("Medelåldern på personerna i filen är: " + sumAge/ageList.size() ); } }catch(IOException e){ e.printStackTrace(); } } }

Dold text

Nej, jag vet att koden inte är speciellt snygg. Detta skall ändras på men nu vill jag få funktionaliteten att fungera.
Har ni några tips? Det som inte fungerar är alltså att få in åldern i arrayen.

Mvh

Edit, får nu ut något svar som absolut inte stämmer, det skrivs ut fyra gånger också men jag verkar kunna konvertera nu iaf.

while((thisLine = br.readLine()) != null){ lineNum++; if (( lineNum % 2) == 1 ){ } else{ Double age = Double.parseDouble(thisLine); ageList.add(age); } }

EDIT igen;

Haha, räknade ut innanför loopen. Tror jag ska lägga mig nu för jag är en jävla idiot. Nu funkar programmet iaf, tack för all input!

Fint att det fungerar. Ett litet tips: du kan snygga till din loop och tomma if-sats genom att lägga till ett 'continue'. 'continue' hoppar till nästa varv i loopen. Men din kod duger bra som den är också!

while((thisLine = br.readLine()) != null){ lineNum++; if (( lineNum % 2) == 1 ) continue; Double age = Double.parseDouble(thisLine); ageList.add(age); }

Trädvy Permalänk
Medlem
Plats
Linköping
Registrerad
Mar 2004

Tack! Håller med, det ser bättre ut!

"Happiness is only real when shared"

Trädvy Permalänk
Medlem
Registrerad
Jun 2015

Undantagshantering

@sebbeharry:

Det är bra ide att skapa och hantera en Exception. Om ngn line med åldern ska innehålla t.ex. bokstav, ska programmet krashas under parsing.

try { //din kod med parsing; } catch (NumberFormatException e) { // satser; }

annars hasNextDouble() innan parsing (om du ska använda Scanner och vill inte thraw exceptions )

Vad tycker du ?
Eller det finns ngn "check" av variabelns typ under inmatning ?