Permalänk
Medlem

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!

Visa signatur

"Happiness is only real when shared"

Permalänk
Medlem

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

Permalänk
Medlem

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.

Visa signatur

"Happiness is only real when shared"

Permalänk
Medlem

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

Visa signatur

Arch - Makepkg, not war -||- Gigabyte X570 Aorus Master -||- GSkill 64GiB DDR4 14-14-15-35-1T 3600Mhz -||- AMD 5900x-||- Gigabyte RX6900XT -||- 2x Adata XPG sx8200 Pro 1TB -||- EVGA G2 750W -||- Corsair 570x -||- O2+ODAC-||- Sennheiser HD-650 -|| Boycott EA,2K,Activision,Ubisoft,WB,EGS
Arch Linux, one hell of a distribution.

Permalänk
Medlem

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

Permalänk
Medlem

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!

Visa signatur

"Happiness is only real when shared"

Permalänk
Medlem

@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
Visa signatur

The difference between stupidity and genius - the latter has limits

Permalänk
Medlem

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!

Visa signatur

"Happiness is only real when shared"

Permalänk
Medlem

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!

Visa signatur

"Happiness is only real when shared"

Permalänk
Medlem
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); }

Permalänk
Medlem

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

Visa signatur

"Happiness is only real when shared"

Permalänk

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 ?