• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

[Java] NullPointerException przy wczytywaniu pliku tekstowego do listy.

Object Storage Arubacloud
0 głosów
362 wizyt
pytanie zadane 22 maja 2017 w Java przez embid123 Użytkownik (630 p.)

Witam ponownie, dziś mam problem z wczytywaniem pliku. Kod: 

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

public class Zad1 {

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

		 BufferedReader x = new BufferedReader(new FileReader("panTadeusz.txt"));

	        String schowek = "";

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

	        do{
	        	schowek = x.readLine().toLowerCase();
	        	list.add(schowek);
	        	}while(schowek!=null);
	        x.close();

	        ArrayList<String> alfabet = new ArrayList<>();
	        ArrayList<Integer> iloscWystapien = new ArrayList<>();
	        ArrayList<String> wykres = new ArrayList<>();

	        schowek = "aąbcćdeęfghijklłmnńoóprsśtuwyzźż";

	        //sporządzanie listy znaków
	        for(int i=0; i<schowek.length(); i++){
	            alfabet.add(Character.toString(schowek.charAt(i)));
	            iloscWystapien.add(0);
	        }

	        for(int i=0; i<list.size();i++){
	            schowek = list.get(i);
	            for(int j=0; j<schowek.length(); j++){
	                String literka = Character.toString(schowek.charAt(j));
	                for(int k=0; k<alfabet.size(); k++){
	                    if(literka.equals(alfabet.get(k))){
	                        iloscWystapien.set(k, iloscWystapien.get(k)+1);
	                    }
	                }
	            }
	        }

	        System.out.println(iloscWystapien);
	
	}
}

Plik tekstowy to treść I księgi "Pana Tadeusza", uprzednio pozbawiony pustych linijek (między wierszami). 

 

Info z konsoli:

Exception in thread "main" java.lang.NullPointerException
    at Zad1.main(Zad1.java:18)- linijka:                 list.add(schowek);
 

1 odpowiedź

+1 głos
odpowiedź 22 maja 2017 przez Mateusz51 Nałogowiec (28,180 p.)
Dlatego że na początku pobierasz potem dodajesz a na koncu sprawdzasz czy to nie był null. Jak Ci wystąpi null to i tak go dodajesz.
komentarz 22 maja 2017 przez embid123 Użytkownik (630 p.)

A no faktycznie, wielkie dzięki. smiley

komentarz 22 maja 2017 przez embid123 Użytkownik (630 p.)

Dalej nie działa. 

 

 schowek = x.readLine().toLowerCase();
	        do{
	        	list.add(schowek);
	        	schowek = x.readLine().toLowerCase();
	        }while(schowek!=null);
	        x.close();

Teraz taki kod dałem. Pierw wczytuję 1 linijkę a w pętli dodaję starą, wczytuję nową i patrzę, czy nie jest nullem. Jak jest, wychodzę z pętli, jak nie to jeszcze raz. 

komentarz 22 maja 2017 przez embid123 Użytkownik (630 p.)
A teraz sam znalazłem błąd. Próbuję na nową linijkę nałożyć metodę toLowerCase() nie sprawdzając wcześniej, czy nie jest nullem. ;)
1
komentarz 22 maja 2017 przez Mateusz51 Nałogowiec (28,180 p.)

mozesz zrobić coś w stylu.

for(String temp = x.readLine(); x!=null; temp=x.readLine()){
   list.add(temp.toLowerCase();
}

 

komentarz 22 maja 2017 przez Mateusz51 Nałogowiec (28,180 p.)
A tak swoją drogą jak iterujesz po całej liscie to polecam używać pętli for each.
komentarz 22 maja 2017 przez embid123 Użytkownik (630 p.)

Już to załatwilem trochę prościej (według mnie). :)

 

schowek = x.readLine();
	        do{
	        	schowek = schowek.toLowerCase();
	        	list.add(schowek);
	        	schowek = x.readLine();
	        }while(schowek!=null);
	        x.close();

Zamiany z dużych na małe dokonuje po uprzednim zatwierdzeniu, że moja linijka nie jest nullem. :) Ale dzięki za kod, zawsze to jakaś nowa wiedza. 

komentarz 22 maja 2017 przez embid123 Użytkownik (630 p.)
A spróbuję, nie ukrywam, ze dopiero sie uczę programować. :)
komentarz 22 maja 2017 przez Mateusz51 Nałogowiec (28,180 p.)
:) Powodzenia w dalszej nauce
komentarz 22 maja 2017 przez Misiek86 Obywatel (1,160 p.)
Nie mam zbyt dużego doświadczenia w programowaniu, ale zamiast do while, użyj po prostu while, bo do while zawsze wykona się przynajmniej raz, jeżeli ktoś poda pusty plik to już przy pierwszej próbie aplikacja się wywali :-)
komentarz 22 maja 2017 przez embid123 Użytkownik (630 p.)
Po prostu zrobię warunek sprawdzajacy czy to null, jak zrobię petlę while i wrzuce pierw ten bufferedreader to znowu będzie sytuacja, ze do listy chcę wcisnąć null'a, nim program sprawdzi czy wlaśnie nullem nie jest.
komentarz 22 maja 2017 przez embid123 Użytkownik (630 p.)
schowek = x.readLine();
		
                if(schowek!=null){
		do {
			schowek = schowek.toLowerCase();
			list.add(schowek);
			schowek = x.readLine();
		} while (schowek != null);
		
                x.close();
                }
                else{
			System.out.println("Nie można wczytywać pustego pliku!");
			System.exit(0);
		}

Teraz będzie OK

komentarz 22 maja 2017 przez Misiek86 Obywatel (1,160 p.)
Raczej myślałem o takim przerobieniu Twojej pętli:

while (schowek != null) {
         schowek = schowek.toLowerCase();
         list.add(schowek);
         schowek = x.readLine();
}
x.close();

 

o ile nic nie pomyliłem ;-)
komentarz 22 maja 2017 przez embid123 Użytkownik (630 p.)
Jeżeli chcesz zastąpić mój cały kod, brakuje x.nextLine();, bez tego schowek jest nullem, pomija tą pętlę i powoduje problemy dalej.
komentarz 22 maja 2017 przez Misiek86 Obywatel (1,160 p.)
package projekt;

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

public class Zad1 {

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

        BufferedReader x = new BufferedReader(new FileReader("C:\\Users\\Piotrek\\Desktop\\panTadeusz.txt"));

        String schowek = "";

        ArrayList<String> list = new ArrayList<>();
        
        schowek = x.readLine();
        
        while (schowek != null) {
            schowek.toLowerCase();
            list.add(schowek);
            schowek = x.readLine();
        };
        x.close();

        ArrayList<String> alfabet = new ArrayList<>();
        ArrayList<Integer> iloscWystapien = new ArrayList<>();
        ArrayList<String> wykres = new ArrayList<>();

        schowek = "aąbcćdeęfghijklłmnńoóprsśtuwyzźż";

        // sporządzanie listy znaków
        for (int i = 0; i < schowek.length(); i++) {
            alfabet.add(Character.toString(schowek.charAt(i)));
            iloscWystapien.add(0);
        }

        for (int i = 0; i < list.size(); i++) {
            schowek = list.get(i);
            for (int j = 0; j < schowek.length(); j++) {
                String literka = Character.toString(schowek.charAt(j));
                for (int k = 0; k < alfabet.size(); k++) {
                    if (literka.equals(alfabet.get(k))) {
                        iloscWystapien.set(k, iloscWystapien.get(k) + 1);
                    }
                }
            }
        }

        System.out.println(iloscWystapien);

    }
}

 

spróbuj teraz :-)
komentarz 22 maja 2017 przez embid123 Użytkownik (630 p.)
Zadziałać zadziała, ale nie widze większej róznicy między do while, a while ;) ogólnie w moich kodach dużo do while używam, jakoś wygodniej mi. ;)
1
komentarz 22 maja 2017 przez Misiek86 Obywatel (1,160 p.)
Różnica jest taka, że gdy robisz

do {
   jakieś_instrukcje
} while (jakiś_warunek)

to jakieś_instrukcje zostaną wykonane co najmniej raz, nawet jeśli jakiś_warunek od początku nie jest spełniony, w przeciwieństwie do pętli

while (jakiś_warunek) {
   jakieś_instrukcje
}

w tej pętli, jeśli jakiś_warunek nie jest spełniony (jego wartość jest false) to jakieś_instrukcje nie zostaną wykonane ani razu :-)

wszystko zależy od tego, co potrzebujesz :-)
komentarz 22 maja 2017 przez embid123 Użytkownik (630 p.)

Też prawda. Moim zdaniem do while bardziej przejrzyście wyglada. :P No dobra, najważniejsze że działa. laugh

komentarz 22 maja 2017 przez Misiek86 Obywatel (1,160 p.)
Tutaj w sumie nie chodzi o to czy bardziej przejrzyście wygląda, tylko o samą funkcjonalność, czasami będziesz potrzebował coś wykonać raz, nawet jeśli warunek nie będzie sprawdzony :-) np. będziesz chciał wylosować liczbę naturalną większą niż 1, ale tylko jedną, ale jednak losować chcesz  z całego zakresu integer, wtedy robisz pętlę

Random generator = new Random();
int x;
do {
  x =  generator.nextInt();
} while (x < 1)

to może nie jest najlepszy przykład, ale może chociaż trochę Ci przedstawi zastosowanie :-)
komentarz 22 maja 2017 przez embid123 Użytkownik (630 p.)
boolean sprawdzaj = false;

Random generator = new Random();
int x = 1;
do {
  x =  generator.nextInt();

if(x==1)
sprawdzaj = true;

} while (sprawdzaj == false)

Czyli mimo, że x = 1, to zalosuje tak? 

komentarz 22 maja 2017 przez Misiek86 Obywatel (1,160 p.)
No tak, jak teraz wrzuciłeś w kodzie, to tak :-)

Mi jednak bardziej chodziło o to, że jeżeli nie zainicjalizowałbyś x nadając mu wartość 1, to losowanie w tej pętli na pewno raz by się odbyło :-) a potem to już w zależności od tego co się wylosuje.
komentarz 22 maja 2017 przez embid123 Użytkownik (630 p.)
No czyli trzeba uważać, dzięki za rady. ;)
komentarz 22 maja 2017 przez Misiek86 Obywatel (1,160 p.)
Nie ma za co :-)

Podobne pytania

0 głosów
0 odpowiedzi 522 wizyt
pytanie zadane 9 czerwca 2017 w Java przez embid123 Użytkownik (630 p.)
–1 głos
1 odpowiedź 171 wizyt
pytanie zadane 30 września 2017 w Java przez Ninja198 Początkujący (330 p.)
0 głosów
1 odpowiedź 159 wizyt
pytanie zadane 14 października 2019 w Java przez heartagram Obywatel (1,770 p.)

92,555 zapytań

141,400 odpowiedzi

319,537 komentarzy

61,938 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...