Codereview klasy vector - prośba o sugestie

0

Uczę się javy od kilku dni. Napisałem klasę vector (niepełną, nie w tym rzecz) dla ćwiczenia. Czy moglibyście zasugerować mi zmiany w kodzie? Chodzi chyba najbardziej o nawyki programowania w javie. Umiem C++ i dla przykładu - ja sam zasugerowałbym bardzo częsty brak modyfikatora const przy definicji/deklaracji funkcji składowej klasy. O tego typu błędy mi chodzi. Chciałbym od początku uczyć się poprawnego programowania w javie mając na uwadze (co najważniejsze) jej wszystkie możliwości.
http://pastebin.com/ZySQcb98
Mam też trzy pytania:

  1. Linie 110, 114, 118: jak zwracać referencje do inta? Chciałbym móc napisać v.front() = 10
  2. Nie ma przeładowania operatorów. Jak zatem jest ten problem rozwiązywany? Ja uznałem, że napisze metodę at(), ale może jest coś przyjemniejszego w korzystaniu.
  3. Chciałbym, żeby stała ERROR była wspólna dla wszystkich obiektów klasy. Jak to zrobić? Metoda z C++z każdą modyfikacją, na którą wpadłem nie działa.
0
  1. Nie musisz pisać, jaki język "znasz", to od razu widać po tym: private int ERROR = -2147483648;
  2. Nie trzymasz się konwencji nazewniczych Javy.
  3. Metoda print nie powinna istnieć. Zadaniem kolekcji nie jest wypisywanie się na konsoli.

Co do Twoich pytań:

  1. Jak uda Ci się coś przypisać do wyniku wywołania metody to zostaniesz moim guru. Tymczasem przestań myśleć o referencjach w ceplusplusowym sensie, i po prostu napisz metodę do zmiany wartości w danej pozycji.
  2. Jeśli to jest problem, to jego jedynym rozwiązaniem jest pisanie w języku, który ma przeładowanie operatorów.
  3. Po co w ogóle taka zmienna? Użyj wyjątków.
0

Metoda print jest wyłącznie do sprawdzenia poprawności kodu.
Co jeśli chcę mieć licznik stworzonych obiektów klasy?
Poza tym - dzięki za uwagi.

0

Dodaj do klasy pole

static int counter = 0;

W konstruktorze zwiększaj wartość pola o 1.
Pole ERROR nie spełnia swojej roli:

vector v = new vector(2,Integer.MIN_VALUE);
System.out.println(v.pob_back()); => -2147483648

A przecież żadnego błędu nie ma. Do sygnalizacji błędu użyj, jak pisał @somekind, wyjątków.
I stosuj Javowe konwencje nazewnicze.

1
nieznajomy112 napisał(a):

Metoda print jest wyłącznie do sprawdzenia poprawności kodu.

To nie ma znaczenia, nie ma miejsca na metodę piszącą na ekran w klasie kolekcji, bo to złamanie zasady SRP. Już większy sens miałoby przeciążenie toString, żeby generowała string z wartościami znajdującymi się w wektorze, a potem dopiero wydrukowanie go na ekran w jakiejś klasie zewnętrznej. A jeśli chcesz sprawdzić poprawność kodu, to napisz testy.

0

Wiem, że print nie powinno istnieć, jednak uważam, że stworzenie takiej metody wyłącznie na potrzeby sprawdzenia poprawności kodu jest okej. Co z dostępem do tej tablicy? Jakie są konwencje powszechnie używane w javie? Metoda at(), czy coś innego?
Kolejne pytanie: czy jest możliwe zaimplementowanie wskaźnikowo struktury danych? Na początku chciałem napisać drzewo binarne, ale zabawa w kursory i ciągłe powiększanie tablicy jest imo średnio fajna.

1
nieznajomy112 napisał(a):

Wiem, że print nie powinno istnieć, jednak uważam, że stworzenie takiej metody wyłącznie na potrzeby sprawdzenia poprawności kodu jest okej.

Trzeci raz powtarzam, TO NIE JEST OK.
I w żaden sposób nie sprawdza poprawności kodu. Ty możesz co najwyżej dzięki temu sprawdzić coś na oko, ale sprawdzanie na oko to zazwyczaj sprawdzanie do d**y.

Kolejne pytanie: czy jest możliwe zaimplementowanie wskaźnikowo struktury danych?

Wskaźniki w Javie? Nie ma i nie są potrzebne.

1

Kolejne pytanie: czy jest możliwe zaimplementowanie wskaźnikowo struktury danych?

Tak, da się zrobić to o czym myślisz. Przy czym osiągniesz to za pomocą referencji, a nie "wskaźników" (których nie ma).

Jak codereview to codereview - dlaczego nie używasz typów generycznych? Taka klasa to idealny kandydat na to.

private int ERROR = -2147483648;

To już zostało skrytykowane więc nie będę powtarzał, ale tak jak było pisane - zły pomysł.

        private int _capacity;
        private int _size;
        private int _Array[]

Po co capacity? Poważnie, odrzuć (złe) przyzwyczajenia z C++. Nie potrzebujesz capacity, bo tablica zna swoją długość.
No i konwencja nazewnicza, underscory (_) przed każdą zmienną są głupie, ale co kto lubi. Ale tak czy inaczej, jeśli zaczynasz pola klasy od małej litery, bądź konsekwentny (_Array <- ?)

        public void reserve (int capacity) {
                if (capacity <= 0)
                        return;
 
                int Temp_array[] = new int[capacity];
                for (int i = 0; i < _size; ++i) {
                        Temp_array[i] = _Array[i];
                }
                _Array = Temp_array;
                _capacity = capacity;
        }

Co się ma dziać kiedy capacity jest mniejsze od obecnego size? Obecnie leci wyjątek (w ogóle po co ERROR skoro wybiórczo lecą wyjątki i zwracasz kody błedu).

        public void print () {
                for (int i = 0; i < _size; ++i) {
                        System.out.println(_Array[i] + " ");
                }
        }

Jak też było pisane, to zły kod. Może i w testowym projekcie dla zabawy nie szkodzi nikomu, ale w normalnym projekcie nie wrzucasz funkcji kompletnie niezwiązanych z działaniem i poziomem abstrakcji klasy do niej. Dlaczego wektor jest zależny od system.out?

Dalej, dwa konstruktory i metoda clear() mają zduplikowane funkcje. Optymalnie jeden konstruktor powininen wywoływać drugi, a drugi wywoływać metodę clear (parametryzowaną), albo coś w tym rodzaju.

//default constructor

Bezsensowne komentarze, to nieprawda że każdy komentarz = lepszy kod. Takie komentarze tylko szkodzą.

        public void push_back (int value) {
                resize (_size + 1, value);
        }

Resize to trochę słaba nazwa na metodę biorąc pod uwagę co ona robi. Ale nie o tym miałem - trzymaj się konwencji nazewniczych języka w którym piszesz, push_back to zła nazwa metody w javie. Tak samo shrink_to_fit i pop_back etc

0

Okej, po poprawkach wygląda to tak:
http://pastebin.com/RaJwAHY2
Nie jestem pewien, czy rzucam odpowiednie wyjątki. A co do nazw obiektów w klasie - underscore stosuję, by dobrze odróżniać zmienne lokalne funkcji od tych w klasie. Natomiast kazdą tablice nazywam z wielkiej litery. Masz rację - co kto lubi, dlatego ta krytyka jest nieco bezsensowna, dopóki jest to "projekt" jednoosobowy.

EDIT: nazwy metod zostały zaczerpnięte z C++ i robią dokładnie to, co robią w STLowym vectorze. A resize właśnie tak tam działa.

0
  1. Czemu nie generic types tylko gołe obiekty?
  2. Rzucaniem jakimś CORBOwym bad_param to WTF ;] IllegalArgumentException jeśli już
  3. Oczy bolą od copypaste w tym kodzie. Jak nie chcesz korzystać z metod z Arrays, np. z "copyOf'' to łaskawie napisz sobie taką metodę a nie kopiujesz 17 razy pętlę z kopiowaniem jednej tablicy do drugiej.

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