Hashtable

0

Mam taki Singleton:
import java.util.Hashtable;
public final class Cennik extends Hashtable {
private final static Cennik c = new Cennik();
private Cennik() {}
public static Cennik getCennik() {
return c;
}

public void set(String produkt, double cena) {
    Hashtable<String,Double> ht = new Hashtable<String, Double>();
    double d =cena;
    String s = produkt;
    ht.put(s, new Double(d));

}

}
Chciałabym w klasie Kasa w metodzie printBill() wypisywać ceny obiektów, ale nie wiem jak niestety.

import java.util.Vector;
class Kasa {
Koszyk k;
public void printBilll(Koszyk k) {
System.out.println("Kasa - rachunek za ["+k +"]:");
for (int i = 0; i < k.size(); i++)
System.out.println();

}

}

0

Skoro już roszerzasz to lepiej rozszerz HashMap i dodaj genericsy czyli zamiast "extends Hashtable" zrób "extends HashMap<String, Double>".

W metodzie set zamiast ht.put(..., ...) zrób po prostu put(..., ...) ponieważ rozszerzasz klasę która tą metodę obsługuje przecież. Nie twórz za każdym razem nowej mapy, bo nie ma po co.

0

To musi być Hashtable.

0

No to niech będzie i Hashtable. Tak samo się go parametryzuje i tak samo implementuje interfejs Map<K, V>.


import java.util.Hashtable;
import java.util.Map;
import java.util.Map.Entry;

class Cennik extends Hashtable<String, Double> {

    private Cennik() {
    }
    
    private static class SingletonHolder {
        private static final Cennik INSTANCE = new Cennik();
    }
    
    public static Cennik getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

class Koszyk extends Hashtable<String, Integer> {

    public synchronized boolean add(String key, Integer value) {
        boolean wasPresent = containsKey(key);
        if (wasPresent) {
            Integer oldValue = get(key);
            put(key, oldValue + value);
        } else {
            put(key, value);
        }
        return wasPresent;
    }
}

public class Main {

    void run() {
        Cennik.getInstance().put("Mleko", 5.0);
        Cennik.getInstance().put("Kakao", 10.0);

        Koszyk koszyk = new Koszyk();
        koszyk.add("Mleko", 5);
        koszyk.add("Kakao", 8);
        koszyk.add("Kakao", 9);

        for (Entry<String, Integer> pozycja : koszyk.entrySet()) {
            String nazwaTowaru = pozycja.getKey();
            Integer ilośćTowaru = pozycja.getValue();
            Double cenaTowaru = Cennik.getInstance().get(nazwaTowaru);
            Double wartośćTowaru = cenaTowaru * ilośćTowaru;
            System.out.println("Typ: " + nazwaTowaru + ", ilość: " + ilośćTowaru +
                    ", cena: " + cenaTowaru + ", wartość: " + wartośćTowaru);
        }
    }

    public static void main(String[] args) {
        new Main().run();
    }
}

0

Trochę nie o to mi chodziło. Przerobiłam moje klasy i mam:
import java.util.Hashtable;
public final class Cennik extends Hashtable {
Hashtable<String,Double> ht = new Hashtable<String,Double>();
private double d;
private String s;
private static Cennik c = new Cennik();
private Cennik() {}
public static Cennik getCennik() {
return c;
}

public void set(String produkt, double cena) {
    d = cena;
    s = produkt;
    ht.put(s, new Double(d));
}

}

import java.util.Vector;
import java.util.Hashtable;
class Kasa extends Hashtable {
Koszyk k;
Hashtable ht;
public void printBilll(Koszyk k) {
System.out.println("Kasa - rachunek za ["+k +"]:");
for (int i = 0; i < k.size(); i++) {
Owoce o =(Owoce) k.get(i);
String s = o.getNazwa();
Object n = ht.get(s);
Double val = (Double) n;
double dv = val.doubleValue();
String napis = dv+ " zł/kg = ";
System.out.println(k.get(i) + " *"+napis);

    }
}

}

Kompiluje się ale potem przy uruchamianiu programu głównego jest tak:
Exception in thread "main" java.lang.NullPointerException
at Kasa.printBilll(Kasa.java:11)

0
  1. Po ch*j robisz "extends Hashtable" (i w dodatku omijasz genericsy!!!) i dajesz pole typu Hashtable? Albo to albo tamto, wystarczy ci jedno Hashtable.

  2. Nie widzę procedury startowej.

0

Po co Cennik dziedziczy po Hashtable, a potem w set do niego deleguje?
Po co Cennikowi pola d i s?
Po co Kasie pole k, skoro Koszyk podaje się jako argument printBill?
Po co Kasie pole ht, skoro dziedziczy po Hashtable?
Po co rzutować obiekty zwracane przez Hashtable.get, skoro można tą kolekcję sparametryzować?
A co do NPE, to zapewne wyrzuca go tutaj:

Object n = ht.get(s);

ht nie jest nigdzie inicjalizowane.

0

//Object n = ht.get(s);
ht nie jest nigdzie inicjalizowane//
jak zainicjalizować?

0
Hashtable ht = new Hashtable<Cośtam, Cośtam>();

(bo ht tylko zadeklarowałaś i wciąż jest nullem)
Ale trzeba to jeszcze czymś wypełnić. Ja naprawdę nie mam pojęcia, do czego to ma służyć. Co się tobie nie podoba w kodzie donkeya?

0

To się wypełnia w klasie głównej przy pomocy metody set (jest w Cenniku)
public void set(String produkt, double cena) {
ht.put(produkt, new Double(cena));
Obiekty tworzą tablicę (przy pomocy klasy Vector z java.util) i teraz chcę z tej tablicy wydostać dla każdego obiektu wartość double metodą z Hashtable get().

0

Okej, ale to zapewne wypełnia obiekt ht z Cennika, drugi taki obiekt ht masz w Kasie. A to dwa różne obiekty :d

0

Fajnie. A nie wiesz może jak zrobić żeby korzystać sobie w klasie Kasa z tego już wypełnionego obiektu?

0
Cennik.getCennik().ht

jeśli ht jest publiczne. Jeśli ma być prywatne, to stworzyć dla niego jakiegoś gettera i wtedy:

Cennik.getCennik().getHt()

ale i to jest bez sensu, bo Cennik już dziedziczy po Hashtable. Najlepiej wywalić z Cennika metodę set(String, double) i wywoływać na jego rzecz put(String, double) (bo taką metodę dziedziczy po Hashtable, jest zresztą wołana w set) i wtedy po prostu w printBill:

Object n = Cennik.getCennik().get(o.getNazwa())

Swoją drogą, twój kod jest rozbity na zbyt dużo zbędnych referencji.

0

Działa w końcu. Dzięki wielkie aniołku.

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