Jak uzyskać typ obiektu i związany z nim String?

0

Dzień dobry,
Jestem w trakcie pisania implementacji kolejki cyklicznej, mam jednak kilka wątpliwości.

  1. Czy metody put() oraz take() działają poprawnie? Program zwraca np. coś takiego:
Odbieram element: 10 po raz: 1
Zamieszczam element: 10 po raz: 1
Zamieszczam element: 10 po raz: 2
Zamieszczam element: 10 po raz: 3
Zamieszczam element: 10 po raz: 4
Zamieszczam element: 10 po raz: 5
Odbieram element: 10 po raz: 2
Odbieram element: 10 po raz: 3
Odbieram element: 10 po raz: 4
Odbieram element: 10 po raz: 5
Exception in thread "main" java.lang.NullPointerException
	at serialize.Circular.toString(Circular.java:311)
	at serialize.CircularMain.main(CircularMain.java:56)

  1. W jaki sposób w metodzie toString uzyskać nazwę typu generycznego? Niestety, obecne rozwiązanie zwraca NullPointerException.
  2. Jak mogę uzyskać napis związany z obiektem?
    Dziękuję za każdą pomoc.
package serialize;

import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.NoSuchElementException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.Iterator;

class Circular<E extends Serializable> implements Serializable, BlockingQueue<E> {
    private final int size;
    private int currentSize;
    //private final BlockingQueue<E> delegate;
    //private 

    private E[] buf;
    private int front;
    private int rear;
    //private int lastElementIndex;

    @SuppressWarnings("unchecked")
    Circular(int size) {
        this.size=size;
        currentSize=0;
        //@SuppressWarnings("unchecked")
        buf = (E[])new Serializable[size];
        front = 0;
        rear = size-1;
    }

    @Override
    public synchronized boolean add(E e) throws IllegalStateException, NullPointerException {
        if(isFull()) {
            throw new IllegalStateException("The buffer is full");
        }
        else if(e==null) {
            throw new NullPointerException();
        }
        rear=incrementWithModulo(rear);
        buf[rear]=e;
        currentSize++;
        return true;
    }

    @Override
    public synchronized E remove() throws NoSuchElementException {
        /*if(o==null) {
            throw new NullPointerException();
        }*/
        if(isEmpty()) {
            throw new NoSuchElementException("You cannot remove an element from empty buffer");
        }

        E element=buf[front];
        buf[front]=null;
        front=incrementWithModulo(front);
        currentSize--;  
        return element;
    }


    @Override
    public synchronized boolean isEmpty() {
        return incrementWithModulo(rear)==front;
    }

    private int incrementWithModulo(int x) {
        return (x+1)%size;
    }

    private boolean isFull() {
        return incrementWithModulo(incrementWithModulo(rear))==front;
    }

    public synchronized E poll() {
        if(isEmpty()) {
            return null;
        }

        E element=buf[front];
        buf[front]=null;
        front=incrementWithModulo(front);
        currentSize--;
        return element;
    }

    public synchronized E take() throws InterruptedException {
        E el=null;
        try{
            if(isEmpty()) {
                monitor("wait");
            }
            el=poll();
            monitor("notify");  //czy to jest w ogóle potrzebne?!
            //return el;
        }
        catch(Exception ex) {
            ex.printStackTrace();
        }
        return el;
    }

    @Override
    public synchronized boolean offer(E e) {
        if(isFull()) {
            return false;
        }

        rear=incrementWithModulo(rear);
        buf[rear]=e;
        currentSize++;
        return true;
    }

    @Override
    public synchronized void put(E e) throws InterruptedException {
        try{
            if(isFull()) {
                monitor("wait");
            }

            offer(e);
            monitor("notify");
        }
        catch(Exception ex) {
            ex.printStackTrace();
        }
    }

    private synchronized void monitor(String intention) throws Exception {
        if(intention.equals("wait")) {
            wait();
        }

        else if(intention.equals("notify")) {
            notifyAll();
        }
    }

    @Override
    public synchronized int size() {
        //return (rear-front)+1;
        return currentSize;
    }

    @Override
    public synchronized boolean remove(Object o) {
        try {
            remove();
        }
        catch(NoSuchElementException e)
        {
            return false;
        }

        return true;
    }

    @Override
    public synchronized E element() {
        /*if(isEmpty()) {
            return null;
        }

        return E;*/

        return isEmpty() ? null : buf[front];
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T> T[] toArray(T[] a) { //nadpisać!!!
        //@SuppressWarnings("unchecked")

        int size=size();
        if(a.length<size) { //zbyt mała tablica wyjściowa
            a=(T[])Array.newInstance(a.getClass().getComponentType(), size);
        }
        else if(a.length>size) {

        }

        int i=0;
        for(E e : this) {
            a[i]=(T)e;
            ++i;
        }

        //a=(T[])buf;
        return a;
    }

    @Override
    @SuppressWarnings("unchecked")
    public E[] toArray() {  //i to!!!
        E[] array=(E[])Array.newInstance(buf.getClass().getComponentType(), size());

        int i=0;
        for(E e : this) {
            array[i]=e;
            ++i;
        }

        return array;
    }

    @Override
    public boolean containsAll(Collection<?> c) {
        return false;
    }

    @Override
    public boolean contains(Object o) {
        return false;
    }

    @Override
    public E peek() {
        return buf[front];
    }

    @Override
    public boolean removeAll(Collection<?> c) {
        return false;
    }

    @Override
    public int remainingCapacity() {
        return -1;
    }

    @Override
    public int drainTo(Collection<? super E> c) {
        return -1;
    }

    @Override
    public int drainTo(Collection<? super E> c, int maxElements) {
        return -1;
    }

    @Override
    public E poll(long timeout, TimeUnit unit) {
        return poll();
    }

    @Override
    public void clear() {

    }

    @Override
    public boolean retainAll(Collection<?> c) {
        return false;
    }

    @Override
    public boolean addAll(Collection<? extends E> c) {
        return false;
    }

    @Override
    public boolean offer(E e, long timeout, TimeUnit unit) {
        return false;
    }

    @Override
    public Iterator<E> iterator() {
        return new CircularIterator();
    }

    class CircularIterator implements Iterator<E> {
        int current=front;
        int last=rear;

        public boolean hasNext() {
            if(incrementWithModulo(current)!=front) {
                return true;
            }
            else {
                return false;
            }
        }

        public E next() {
            if(!hasNext()) {
                throw new NoSuchElementException();
            }
            
            int tempCurrent=current;
            current=incrementWithModulo(current);
            return buf[tempCurrent];
        }
    }

    public String toString() {
        E element=null;
        String result="";

        for(int i=0; i<size; ++i) {
            int x=i-front<0 ? (size-i)-front : i-front;
            //E element=(E)0;
            
            //System.out.println(i+"  "+(i-front)+" "+element.getClass().getSimpleName());

            if(buf[i]==null) {
                result+=i+"  "+x+" "+element.getClass().getSimpleName()+"   Empty";
            }
            else {
                result+=i+"  "+x+" "+element.getClass().getSimpleName()+"   "+buf[i];
            }
            //Rozwiązanie nie jest idealne, ale może zadziała w konkretnym przypadku
        }
        return result;
    }
}


package serialize;

import java.io.Serializable;

class CircularTest implements Runnable {

    private Integer element;
    private Integer secondElement;
    private Circular<Integer> circular;
    String name;

    CircularTest(Circular<Integer> circular, String name) {
        this.circular=circular;
        this.name=name;
        element=name.equals("Producer") ? 10 : 5;
    }

    void produce() throws InterruptedException {
        circular.put(element);
    }

    void consume() throws InterruptedException {
        secondElement=circular.take();
    }

    public void run() {
        for(int i=1; i<6; ++i) {
            try {
                if(name.equals("Producer")) {
                    produce();
                    System.out.println("Zamieszczam element: "+element+" po raz: "+i);
                }
                else if(name.equals("Consumer")) {
                    consume();
                    System.out.println("Odbieram element: "+secondElement+" po raz: "+i);
                }
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}


package serialize;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class CircularMain {
    
    public static void main(String[] args) {
        Circular<Integer> circular=new Circular<>(10);
        
        CircularTest prod=new CircularTest(circular, "Producer");
        CircularTest kons=new CircularTest(circular, "Consumer");

        Thread p=new Thread(prod);
        Thread k=new Thread(kons);

        p.start();
        k.start();

        try{
            p.join();
            k.join();
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }

        Circular<Double> secondCircular=new Circular<>(10);
        for(int i=0; i<7; ++i) {
            secondCircular.add((double)i);
        }

        try(ObjectOutputStream objectOutputStream=new ObjectOutputStream(new FileOutputStream("circular_buffer.ser"))) {
            objectOutputStream.writeObject(secondCircular);
            objectOutputStream.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }

        @SuppressWarnings("unchecked")
        Circular<Double> resultCircular=null;
        try(ObjectInputStream objectInputStream=new ObjectInputStream(new FileInputStream("circular_buffer.ser"))) {
            resultCircular=(Circular<Double>)objectInputStream.readObject();
            objectInputStream.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }

        if(resultCircular!=null) {
            System.out.println("/n"+resultCircular.toString());
        }
    }
}
0

Rzuca wyjątek bo w pętli metody toString():

 E element=null;

a potem robisz coś takiego

 if(buf[i]==null) {
        result+=i+"  "+x+" "+element.getClass().getSimpleName()+"   Empty";
      }
      else {
        result+=i+"  "+x+" "+element.getClass().getSimpleName()+"   "+buf[i];
      }
      //Rozwiązanie nie jest idealne, ale może zadziała w konkretnym przypadku

wywołujesz metodę na null'u. Iterujesz po całej tablicy a nie od front do rear.
Pojemność struktury to capacity a liczba elementów to size. Wartość rear możesz obliczyć na podstawie front i size(), więc wywal to pole i napisz metodę np int rear(). Pusta kolejka ma wartość size=0 a pełna size == capacity, więc te warunki powinny być w metodach isEmpty() i isFull(). Twoje też są poprawne, ale wymagają dodatkowego obliczenia wyrażenia.

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