Zapis do pliku - nie może zapisać tabeli.

0

Ogarniam dopiero zapis i odczyt z pliku i mam pewną koncepcję programu i najpierw chciałem przetestować samo działanie na plikach i według tego co wyczytałem poniższy kod powinien działać:


package javaapplication34;

import java.io.*;

class Przedmioty {
    private String przedmiot, nauczyciel;
    private int[][] oceny;
    private double srednia;
    private int ilosc_ocen;
    public void nadaj(String q, String w,double e, int r, int[][] t){
        przedmiot = q;
        nauczyciel = w;
        srednia = e;
        ilosc_ocen = r;
        oceny = new int[t.length][1];
        for(int i=0;i<oceny.length;i++){
            oceny[i][0] = t[i][0];
            oceny[i][1] = t[i][1];
        }
    }
    public String zwroc_przedmiot(){
        return przedmiot;
    }
    public String zwroc_nauczyciela(){
        return nauczyciel;
    }
    public double zwroc_srednia(){
        return srednia;
    }
    public int zwroc_ilosc_ocen(){
        return ilosc_ocen;
    }
    public int zwroc_ocene(int j, int k){
        return oceny[j][k];
    }
}

public class Main {

    static Integer ilosc_przedmiotow = new Integer(4);
    
    public static void main(String[] args) throws IOException {
        Przedmioty[] przedmioty;
        przedmioty = new Przedmioty[ilosc_przedmiotow];
        ilosc_przedmiotow = new Integer(przedmioty.length);
        int[][] cyferki = {
            {4,2},{3,1},{5,3}
        };
        for(int i=0; i<przedmioty.length;i++){
               przedmioty[i].nadaj("Polski", "Nowak", 4.2, 3, cyferki);
        }

        FileWriter fw = new FileWriter("plik.txt");
        FileReader fr = new FileReader("plik.txt");
        BufferedReader br = new BufferedReader(fr);
        fw.write(ilosc_przedmiotow.toString()+"\n");
        for(int i=0; i<przedmioty.length;i++){
            fw.write(przedmioty[i].zwroc_przedmiot()+"\n");
            fw.write(przedmioty[i].zwroc_nauczyciela()+"\n");
            fw.write(Double.toString(przedmioty[i].zwroc_srednia())+"\n");
            fw.write(Integer.toString(przedmioty[i].zwroc_ilosc_ocen())+"\n");
            for(int j=0;j<przedmioty[i].zwroc_ilosc_ocen();j++){
                fw.write(przedmioty[i].zwroc_ocene(j, 0)+"\n");
                fw.write(przedmioty[i].zwroc_ocene(j, 1)+"\n");
            }
        }
        fw.close();

        String s;

        while((s = br.readLine()) != null)
			{
			System.out.println(s);
			}
    }

}
 

W linii: przedmioty[i].nadaj("Polski", "Nowak", 4.2, 3, cyferki); wyrzuca wyjątek: java.lang.NullPointerException. Już miałem to samo wcześniej gdy przypisywałem dwie tablice oceny = t; ale gdy dodałem funkcję "nadaj()" gdzie przypisuję po kolei wartości z komórek tabeli 'oceny' do komórek 't' nadal wyrzuca ten wyjątek. Domyślam się, że związane jest to z tym, że rozmiar tabeli jest podawany dopiero po uruchomieniu programu ale tak w zamyśle musi być, bo każdy użytkownik może mieć inne dane, lecz nie wiem w którym miejscu jest błąd.

Dałem tą linijkę w komentarz by zobaczyć co się stanie i ten sam wyjątek pokazało w linii: fw.write(przedmioty[i].zwroc_przedmiot()+"\n");

Proszę o pomoc.

1

Po instrukcji

przedmioty = new Przedmioty[ilosc_przedmiotow];

każdy element tablicy przedmioty jest równy null. Musisz tablicę wypełnić "Przedmiotami".

for(int i=0;i<przedmioty.length;i++)
{
   przedmioty[i]=new Przedmioty();
}

Zostanie wtedy użyty domyślny konstruktor bezargumentowy. Ja bym napisał konstruktor robiący, to co metoda nadaj().

    public Przedmioty(String q, String w,double e, int r, int[][] t){
        przedmiot = q;
        nauczyciel = w;
        srednia = e;
        ilosc_ocen = r;
        oceny = new int[t.length][1];
        for(int i=0;i<oceny.length;i++){
            oceny[i][0] = t[i][0];
            oceny[i][1] = t[i][1];
        }
//oraz
   for(int i=0; i<przedmioty.length;i++){
          przedmioty[i]=new Przedmioty("Polski", "Nowak", 4.2, 3, cyferki);
   }
//zamiast
   for(int i=0; i<przedmioty.length;i++){
          przedmioty[i].nadaj("Polski", "Nowak", 4.2, 3, cyferki);
   }

0

Dzięki wielkie, wprowadziłem te zmiany i działa:) Tzn. od razu nie działało, bo wyrzuciło wyjątek java.lang.ArrayIndexOutOfBoundsException ale to dlatego, że w linii:

oceny = new int[t.length][1];

powinno być

oceny = new int[t.length][2];

Potem już wszystko ładnie zapisywało i odczytywało:)

Edit:

Pytanko bym miał jeszcze troszkę inne. Jak teraz zapisałem sobie te dane wszystkie i przy odczytywaniu pierwszą linie jaką odczytuję to będzie ilość przedmiotów i potem na podstawie tej ilości będzie pętla tworząca elementy tablicy 'przedmioty' no i wstawiająca do niej odczytane dane ale jak np. użytkownik chciałby usunąć albo dodać przedmiot to trzeba będzie zwiększyć albo zmniejszyć rozmiar tablicy 'przedmioty' (lub oceny w przypadki dodawania, usuwania ocen) tylko jak to zrobić, żeby nie tworzyć nowej tablicy i nie utracić danych?

0

Powinieneś zmienić tablicę oceny na kolekcję. W kolekcjach łatwo modyfikuje się rozmiar (dodaje nowy element, usuwa niepotrzebny).
BTW. Dlaczego nasz w klasie Przedmioty pole srednia, któremu nadajesz wartość nie mającą związku z ocenami? Średnia powinna być wyliczana na podstawie ocen.

0

Powinieneś zmienić tablicę oceny na kolekcję. W kolekcjach łatwo modyfikuje się rozmiar (dodaje nowy element, usuwa niepotrzebny).
BTW. Dlaczego nasz w klasie Przedmioty pole srednia, któremu nadajesz wartość nie mającą związku z ocenami? Średnia powinna być wyliczana na podstawie ocen.

0

To jest taka klasa "beta" zrobiona na poczekaniu, chodzi mi głównie o sprawdzenie tego zapisywania, odczytywania no i edycji odczytanych danych dlatego z tą średnią tak wyszło. Co do tej edycji danych to myślałem, o stworzeniu drugiej tablicy z obiektami Przedmioty tylko o jeden rekord większą, skopiowanie do niej wartości z tej pierwszej a do ostatniego rekordu wpisać dane podane przez użytkownika (docelowo program ma on być w Swingu) i to jest do zrobienia przy dodawaniu nowego Przedmiotu, ale gdy użytkownik będzie chciał usunąć jakiś przedmiot ze środka tablicy to taka metoda stwarza już troszkę problemów. Mówiąc kolekcje masz namyśli ArrayList? Poszukałem troszkę, poczytałem i powiem szczerze, że nie korzystałem z tego i nie bardzo wiem jak tego użyć;/

0

Tak, chodzi mi o ArrayList. Mógłbym krótko naszkicować jak jej użyć w Twoim programie, ale nie wiem dlaczego tablica oceny jest dwuwymiarowa i do czego "służą" te wymiary.

0

Oceny są dwuwymiarowe ponieważ komórka [0] to ocena a [1] to jej waga (do liczenia średniej wagowej).

1

Dodałem nową klasę OcenaZWaga i przerobiłem pole oceny na ArrayList.

package tmp;

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

class OcenaZWaga
{
    protected float ocena;
    protected float waga;
    public OcenaZWaga(float ocena,float waga)
    {
        this.ocena=ocena;
        this.waga=waga;
    }
}

class Przedmioty {
    private String przedmiot, nauczyciel;
    private ArrayList<OcenaZWaga> oceny;
    //private double srednia;
    //private int ilosc_ocen;

    public Przedmioty(String q, String w, ArrayList<OcenaZWaga> t)
    {
        przedmiot = q;
        nauczyciel = w;
        //srednia = e;
        //ilosc_ocen = r;
        oceny = new ArrayList<OcenaZWaga>();
        for(int i=0;i<t.size();i++)
        {
            oceny.add(t.get(i));
        }
    }
    public String zwroc_przedmiot(){
        return przedmiot;
    }
    public String zwroc_nauczyciela(){
        return nauczyciel;
    }
    public double zwroc_srednia(){
        float suma=0f;
        float wagi=0f;
        for(int i=0;i<oceny.size();i++)
        {
            suma+=oceny.get(i).ocena*oceny.get(i).waga;
            wagi+=oceny.get(i).waga;
        }
        return suma/wagi;
    }
    public int zwroc_ilosc_ocen(){
        return oceny.size();
    }
    public float zwroc_ocene(int j){
        return oceny.get(j).ocena;
    }
    public float zwroc_wage(int j){
        return oceny.get(j).waga;
    }
    public void usun(int i)
    {
        oceny.remove(i);
    }
    public void dodaj(OcenaZWaga ocena)
    {
        oceny.add(ocena);
    }
}

public class Main {

    static Integer ilosc_przedmiotow = new Integer(4);

    public static void main(String[] args) throws IOException {
        Przedmioty[] przedmioty = new Przedmioty[ilosc_przedmiotow];
        //ilosc_przedmiotow = new Integer(przedmioty.length);
        ArrayList<OcenaZWaga> cyferki = new ArrayList<OcenaZWaga>();
        cyferki.add(new OcenaZWaga(4.0f,2.0f));
        cyferki.add(new OcenaZWaga(3.0f,1.0f));
        cyferki.add(new OcenaZWaga(5.0f,3.0f));
        for(int i=0; i<przedmioty.length;i++){
               przedmioty[i]=new Przedmioty("Polski", "Nowak",cyferki);
        }
        przedmioty[0].usun(1);
        przedmioty[1].dodaj(new OcenaZWaga(3.5f,2.0f));

        FileWriter fw = new FileWriter("plik.txt");
        FileReader fr = new FileReader("plik.txt");
        BufferedReader br = new BufferedReader(fr);
        fw.write(ilosc_przedmiotow.toString()+"\n");
        for(int i=0; i<przedmioty.length;i++){
            fw.write(przedmioty[i].zwroc_przedmiot()+"\n");
            fw.write(przedmioty[i].zwroc_nauczyciela()+"\n");
            fw.write(Double.toString(przedmioty[i].zwroc_srednia())+"\n");
            fw.write(Integer.toString(przedmioty[i].zwroc_ilosc_ocen())+"\n");
            for(int j=0;j<przedmioty[i].zwroc_ilosc_ocen();j++){
                fw.write(przedmioty[i].zwroc_ocene(j)+"\n");
                fw.write(przedmioty[i].zwroc_wage(j)+"\n");
            }
        }
        fw.close();

        String s;

        while((s = br.readLine()) != null)
                        {
                        System.out.println(s);
                        }
    }

}
0

Ojej człowieku jak ja Ci się odwdzięczę to nie mam pojęcia. Listy śmigają aż miło, w głównej klasie zrobiłem sobie też listę Przedmiotów i też ładnie się usuwają i zmieniają. Dzięki ogromne:-)

1 użytkowników online, w tym zalogowanych: 0, gości: 1