Prosty Stos

0

Witam, napisałem prosty stos, i niestety otrzymuje NullPointerException...
Co przeoczyłem, czego nie zainicjowałem:

public class MojStos {
	Object tab[];
	int counter;
	
	
	public MojStos(int wielkosc){
		Object tab[] = new Object[wielkosc];
		counter = 0;
	}
	
	public void push(Object o)throws StosPrzepelnionyException{
		if(tab.length>counter){
			tab[counter++]=o;
		} else {
			throw new StosPrzepelnionyException();
		}
	}
	public Object pop() throws StosPustyException{
		if(counter<=0){
			throw new StosPustyException();
		} else {
			return tab[--counter];
		}
	}
	
	public void show(){
		/*for(Object item : tab){
			System.out.println(tab[item]);
		}*/
		System.out.println("===============");
		for(int i=0;i<=tab.length;i++){
			System.out.println(tab[i]);
		}
		System.out.println("===============");
		
	}
	
}

Klasa Main

public class Main {
	
	public static void main(String[] args) {
		MojStos ms = new MojStos(3);
		
	
		try {
			ms.push(new Integer(8));
		} catch (StosPrzepelnionyException e) {
			e.printStackTrace();
			}
		}
	}
0

W konstruktorze nie inicjujesz pola.

0

I tab i counter sa są przeciez zainicjowane?
tab = new Object(wielkosc);
counter = 0;

0

Jak już wycinasz fragment, wycinaj z kontekstem:

Object tab[] = new Object[wielkosc];
// ^^^^^^^^

;-)

0

Tu jest stos od autorow Algorytmow w Javie https://algs4.cs.princeton.edu/13stacks/Stack.java.html

0

Cześć,
W konstruktorze tworzysz zupełnie nowy obiekt, który nic Ci nie daje później. Zamiast tego odwołaj się do zmiennych klasy:

    public MojStos(int wielkosc){
        Spojler alert. Masz drugą zmienną i wymyśl co z pierwszą i zastanów się dlaczego tak jest:)
        this.counter = 0;
    }

i z tego co widzę jeszcze powinno Ci wywalić ArrayOutOfBoundException przy:

        for(int i=0;i<=tab.length;i++){
            System.out.println(tab[i]);
        }

iterujesz o jeden obiekt za dużo. Sam zmień :)

Pozdrawiam,
adaszewski95

0

W konstruktorze tworzysz zupełnie nowy obiekt, który nic Ci nie daje później. Zamiast tego odwołaj się do zmiennych klasy:

    public MojStos(int wielkosc){
        Spojler alert. Masz drugą zmienną i wymyśl co z pierwszą i zastanów się dlaczego tak jest:)
        this.counter = 0;
    }

Hey, dzieki za odpowiedzi, dlaczego mówisz ze tworze obiekt który nic mi nie daje. Tworze Objekt Tab (tj. moj stos). To obiekt wiec muszę go zainicjować.

0

i z tego co widzę jeszcze powinno Ci wywalić ArrayOutOfBoundException przy:

        for(int i=0;i<=tab.length;i++){
            System.out.println(tab[i]);
        }

iterujesz o jeden obiekt za dużo. Sam zmień :)

jasna sprawa już poprawione:)

1

Dobre rano :)

Już Ci tłumaczę, bo to jest kluczowe. Zauważ, że w klasie masz dwie **zdefiniowane **zmienne:

    Object tab[];
    int counter;

Następnie tworzysz konstruktor, co jest jak najbardziej logiczne. Tylko w tym konstruktorze kluczowe jest to, żeby przypisać wartość zmiennym, które wcześniej zdefiniowałeś. Czyli tym powyżej. A to co robisz Ty w tym konstruktorze:

    public MojStos(int wielkosc){
        Object tab[] = new Object[wielkosc];
        counter = 0;
    }

jest zdefiniowanie nowych zmiennych, które nie mają nic wspólnego z Twoimi zmiennymi klasy.
Zmienne, które zdefiniowałeś i przypisałeś im wartość w konstruktorze widzi tylko ten obiekt. Co to powoduje? Że do Twoich zmiennych klasy nie została przypisana żadna wartość a Ty próbujesz z nich skorzystać w dalszych metodach (myśląc, że przypisałeś im wartość, a tak na prawdę stworzyłeś nowe zmienne, które nie są widoczne poza konstruktorem) co skutkuje NullPointerem, ponieważ po stworzeniu obiektu nie zostały przypisane wartości zmiennym klasy. Dlatego też musisz koniecznie przypisać tym zmiennym wartość w konstruktorze. Tzn teraz patrzę to counterowi przypisujesz ale tworzysz tylko new Object tab = ...
Po prostu napisz tab = ... i będzie gitarrra :D
Mam nadzieję, że wytlumaczyłem zrozumiale.

Pozdrawiam,
adaszewski95

1

pare uwag odnosnie twojego stosu ktore mozna latwo poprawic:

  • moglby byc type safe zamiast uzywac object
  • moglby nie rzucac wyjatkami
  • mogby nie miec ograniczen jesli chodzi o rozmiar
  • moglby nie miec wyciekow pamieci (przy pop)

np:

import java.util.Optional;

public class Stack<TElement> {

    private Node<TElement> top;

    public void push(TElement element) {
        top = new Node<>(element, top);
    }

    public Optional<TElement> pop() {
        if (top == null) {
            return Optional.empty();
        }
        TElement popped = top.value;
        top = top.below;
        return Optional.of(popped);
    }

    public void show() {
        System.out.println("===============");
        Node current = top;
        while (current != null) {
            System.out.println(current.value);
            current = current.below;
        }
        System.out.println("===============");

    }

    private class Node<TElement> {
        final TElement value;
        final Node<TElement> below;

        Node(TElement value, Node<TElement> below) {
            this.value = value;
            this.below = below;
        }
    }


    public static void main(String[] args) throws Exception {
        Stack<String> stack = new Stack<>();
        stack.push("lol");
        stack.push("rotfl");
        stack.push("lmao");
        stack.show();
        stack.pop();
        stack.pop();
        stack.show();
        stack.pop();
        stack.pop();
    }
}
0
adaszewski95 napisał(a):

Dzięki za wskazówki. Zrobiłem poniższe:

	public MojStos(int wielkosc){
		this.tab = new Object[wielkosc];
		this.counter = 0;
	}

Odwołuje się do konkretnych pól klasy które inicjuje w konstruktorze (błąd NullpointException rozwiązany :)

0

Co znaczy?

  • moglby nie miec wyciekow pamieci (przy push)
2

mialam na mysli pop.
gdy bierzesz obiekty ze stosu to nie usuwasz ich z tablicy, tak wiec nawet jesli przestaniesz ich uzywac w innych miejscach, to referencja bedzie dalej trzymana i garbage collector ich nie usunie.
rozwiazaniem na ten problem (w twoim kodzie) byloby:

counter--;
Object element = tab[counter];
tab[counter] = null;
return element;

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