dodawanie do mapy a nullexceptionpointer

0

Witam.
Próbuję dodawać słowa i ilość wystąpień danego słowa w danym pliku. Robię to w ten sposób:

String word;
Integer count = 0;
while (!inFile.eof()){
					word = inFile.readWord();
					//JOptionPane.showMessageDialog(this, Slowa.containsKey(word));
					//Slowa.put(word, count);
					
					try {
						if(Slowa.containsKey(word))
							count++;
						
						Slowa.put(word, count);
					} catch(NullPointerException e) {
						JOptionPane.showMessageDialog(this, "Rzucam wyjątkiem");
					}
}

i mimo że nie widzę błędu to ciągle zgłasza mi wyjątek.
Proszę o pomoc.
Pozdr

0

Zapewne Slowa jest nullem. Poza tym robisz to w tak słaby sposób że aż smutno. Może jednak java 8 i ładne grupowanie?

0
TreeMap <String, Integer> Slowa = new TreeMap<String, Integer>();

Jak to w takim razie naprawić? Nigdzie nulla nie przypisuję.

0
  1. A możesz pokazac GDZIE leci ten null?
  2. Szklana kula mówi że w takim razie próbujesz dodać do mapy klucz który jest nullem.
0
Shalom napisał(a):

Poza tym robisz to w tak słaby sposób że aż smutno. Może jednak java 8 i ładne grupowanie?

@Shalom
Możesz pokazać jak by takie grupowanie wyglądało?

0

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at java.util.TreeMap.getEntry(TreeMap.java:347)
at java.util.TreeMap.containsKey(TreeMap.java:232)
at Reader.actionPerformed(Reader.java:70)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6535)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
at java.awt.Component.processEvent(Component.java:6300)
at java.awt.Container.processEvent(Container.java:2236)
at java.awt.Component.dispatchEventImpl(Component.java:4891)
at java.awt.Container.dispatchEventImpl(Container.java:2294)
at java.awt.Component.dispatchEvent(Component.java:4713)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
at java.awt.Container.dispatchEventImpl(Container.java:2280)
at java.awt.Window.dispatchEventImpl(Window.java:2750)
at java.awt.Component.dispatchEvent(Component.java:4713)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.awt.EventQueue$4.run(EventQueue.java:729)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

Wypisywałem sobie zmienną word i za każdym razem miałem jakieś "wartości".

0

Jak wygląda ten

at Reader.actionPerformed(Reader.java:70)
wiersz?
Moja szklana kula mówi, że masz pole w klasie i zmienną lokalną o nazwie Slowa. Jedna z nich jest nullem, a do drugiej próbujesz dodawać słowa.

1

A jaki jest format pliku? Zakładam że masz po prostu słowa przedzielone spacjami i wtedy:

        Map<String, Long> map = Files.lines(Paths.get("teksty.txt"))
                .flatMap(line -> Arrays.stream(line.split(" ")))
                .collect(Collectors.groupingBy(
                        Function.identity(),
                        Collectors.counting()
                ));

To ci zwróci mapę wystąpień dla wszystkich słów w pliku teksty.txt

0

@Shalom Twój kod też nie działa:

Exception in thread "main" java.io.UncheckedIOException: java.nio.charset.MalformedInputException: Input length = 1
at java.io.BufferedReader$1.hasNext(BufferedReader.java:574)
at java.util.Iterator.forEachRemaining(Iterator.java:115)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at Reader.<init>(Reader.java:45)
at Reader.main(Reader.java:99)
Caused by: java.nio.charset.MalformedInputException: Input length = 1
at java.nio.charset.CoderResult.throwException(CoderResult.java:281)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at java.io.BufferedReader$1.hasNext(BufferedReader.java:571)
... 9 more

0

To może wreszcie pokażesz łaskawie JAK WYGLĄDA PLIK Z DANYMI? Bo przeciez napisałem ci że mój kod zakłada pewną strukturę pliku i dla takiej struktury działa bez zarzutu...

0

fragment artykułu z niebezpiecznika.

0

I nie widzisz w tym pliku nic dziwnego? Na przykład rozwalonego kodowania? o_O Zapisz ten plik z danymi w sposób poprawny, najlepiej jako UTF-8.
Domyslam sie też ze konieczne będzie dla ciebie zapoznanie się (ze zrozumieniem!) z http://www.joelonsoftware.com/articles/Unicode.html

0

Teraz wyrzuca mi wyjątek w tym miejscu (NullPointer):

for (String klucz : map.keySet()) {
			String wartosc = Long.toString(map.get(klucz));
			String[] wiersz = { klucz, wartosc };
			modelTabeli.addRow(wiersz);
    	}
0

Nie rozumiem co ty tu wyprawiasz.

  1. .entrySet() zwróci ci parę klucz,wartość z mapy
  2. .toString() na longu zwróci ci stringa
  3. GDZIE ten wyjątek, bo przeciez nie w całym bloku...
0

Poprawiłem to co wyżej napisałeś, wrzucę całą klasę która wyświetla mi zawartość mapy:

class WidokMapy extends JScrollPane {
	private static final long serialVersionUID = 1L;

	private JTable tabela;
	private DefaultTableModel modelTabeli;
	private Map<String, Long> map;

	WidokMapy(Map<String, Long> map, int szerokosc, int wysokosc,
			String opis) {
		String[] kolumny = { "Słowo:", "Ilość:" };
		modelTabeli = new DefaultTableModel(kolumny, 0);
		tabela = new JTable(modelTabeli);
		tabela.setRowSelectionAllowed(false);
		this.map = map;
		setViewportView(tabela);
		setPreferredSize(new Dimension(szerokosc, wysokosc));
		setBorder(BorderFactory.createTitledBorder(opis));
	}

	void refresh(){
    	modelTabeli.setRowCount(0);

		for (Map.Entry<String, Long> entry : map.entrySet())
		{

		    String[] wiersz = { entry.getKey(), Long.toString(entry.getValue()) };
		    modelTabeli.addRow(wiersz);
		}
    }

}

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at WidokMapy.refresh(Reader.java:132)
at Reader.actionPerformed(Reader.java:100)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
.
.
.

Linia 132:

for (Map.Entry<String, Long> entry : map.entrySet())

Linia 100: widokSlowa.refresh();

0

Serio nie potrafisz używać debugera? Kliknasz na tej linii i dajesz "add breakpoint" a następnie uruchamiasz program w debug mode. I patrzysz gdzie coś się kaszani. Zapewne z jakiegoś powodu map jest nullem.

0

Jak wrzucam ten Twój kod do konstruktora (a nie do przeciążonej metody actionPerformed) to działa bez zarzutów.

0

No ale przecież jak nie wywołasz tego kodu wcześniej to mapa nie jest stworzona i odwołania do niej będą rzucać wyjątkiem. Nie bardzo rozumiem co cię w tej kwestii dziwi.

0

mam tak:

public class Foo ... {
...
Map<String, Long> map;
...
Foo() {
...
}

public void actionPerformed(ActionEvent evt) {
...
map = Files.lines(Paths.get(fileName))
			                .flatMap(line -> Arrays.stream(line.split(" ")))
			                .collect(Collectors.groupingBy(
			                        Function.identity(),
			                        Collectors.counting()
			                ));
...
}
...
}

To przypisywanie wartości musi się znaleźć w actionPerformed bo dopiero tam dowiaduję się jaka jest ścieżka do pliku.

0

No dobra ale wtedy twoje refresh nie moze sie wykonać PRZED tym actionPerformed. Tzn jak zrobisz to z głową to może -> po prostu zrób:
Map<String, Long> map = new HashMap<>();
przy deklaracji pola i voila.

0

Próbowałem już tak ale nie działało. Tzn nie wyrzuca żadnych wyjątków ale metoda refresh nic nie wypisuje...

0

No ale CO ma niby wypisać ZANIM nie wczytasz czegoś do mapy? o_O

0

Czyli rozumiem że Twoim sposobem nie rozwiążę mojego problemu, bo żeby program działał prawidłowo to kod wczytujący do mapy musi się znajdować w actionPerformed, a Twój nadaje się tylko do konstruktora.

0

Nie, nic nie rozumiesz. Mój kod działa niezależnie od tego gdzie go wstawisz. To ty robisz jakieś cuda na kiju które wysypują twój program. Moja rada: naucz sie używać debugera i używaj go. Bo najwyraźniej ty nie rozumiesz kiedy i co się w twoim programie wywołuje.
Szklana kula mówi mi że twoje "refresh" może sie wywołać zanim wczytać cokolwiek do mapy, więc musisz albo mieć na starcie pustą mapę albo sprawdzać w tej metodzie czy mapa aby czasem nie jest pusta.

0

Dodałem sprawdzanie czy mapa jest pusta i jest. Możliwe że się potem wypełnia ale nie wiem wtedy jak ją wylistować.

0

To ja proponuje żebyś zaczął naukę programowania od podstaw, bo to co piszesz wskazuje jedynie że masz bardzo niewielkie pojęcie o tym co robisz.

0

Znam podstawy, nie potrafię obsługiwać debugera, tzn wiem co i jak włączyć ale te miliony zmiennych, wszystkie poustawiane na wartości które nic mi nie mówią. Zasady programowania obiektowego znam. Według mnie wszystko w tym programie wygląda dobrze (Twojego kodu nie rozumiem jedynie), to w jaki sposób robiłem to na początku było dla mnie czytelniejsze.

0

Ale mój kod robi dokładnie to samo co twój, to jest akurat zupełny szczegół. Problem w tym że właśnie nie rozumiesz zasad programowania obiektowego skoro nie rozumiesz jak i kiedy wypełniają się na przykład pola w twojej klasie. A debugera musisz sie nauczyć w takim razie bo pisanie czegoś więcej niż helloworld będzie po prostu męką.

Nie wiem jak wygląda ten twój kod, ale generalnie swoje refresh powinieneś wywołać dopiero PO tym jak wywołasz tego actionListenera ustawiającego mapę. Jak go wywołasz wcześniej to się wysypie. Możesz ustawić pole w klasie na pustą mapę na start ale nie zmienia to faktu że musisz zawołać to refresh po wczytaniu faktycznych danych do mapy.

0
public void actionPerformed(ActionEvent evt) {
    	...
    	Object zrodlo = evt.getSource();
    	
    	if (zrodlo == przyciskOk) { 
			String fileName = poleWiersz.getText();
			if (!fileName.equals(""))
       	    { 
				try{
			     	map = Files.lines(Paths.get(fileName))
			                .flatMap(line -> Arrays.stream(line.split(" ")))
			                .collect(Collectors.groupingBy(
			                        Function.identity(),
			                        Collectors.counting()
			                ));
			     	} catch(IOException e)
			     	{
			     		JOptionPane.showMessageDialog(this, "Err!");
			     		System.exit(1);
			     	}
            }
    	}
...
    	widokSlowa.refresh();
    }

Jak widać metoda refresh() jest wywołana poza if'em który wypełnia mapę. Tak więc najpierw (jeśli spełniony jest warunek, a jest!) wypełnia się mapa a potem po wyjściu z if'a natrafia na refresh().

0

O RLY? A ja idę o zakład że ten actionListener obsługuje też inne zdarzenia, takie dla których te ify nie są spełnione. Nie wierzysz? No to daj breakpoint wewnątrz tych 2 ifów oraz na refresh i odpal aplikację. Zobaczysz (szklana kula nie kłamie!) że debugger zatrzyma się na refresh a nie wewnarz ifów bo warunek nie jest spełniony w jakiejś sytuacji. Następnie przeanalizuj jaka to sytuacja (masz stos wiec możesz patrzeć "skąd wywołano" twojego actionListenera) i masz stan zmiennych więc widzisz czemu warunki nie przeszły).

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