Programovanie (2) v Jave
1-INF-166, LS 2017/18

Úvod · Pravidlá · Prednášky · Netbeans · Testovač · Test a skúška
· Vyučujúcich môžete kontaktovať pomocou e-mailovej adresy E-prg.png (bude odpovedať ten z nás, kto má príslušnú otázku na starosti alebo kto má práve čas).
· DÚ10 je zverejnená, odovzdávajte do stredy 16.5. 22:00.
· Bonusový projekt odovzdávajte do pondelka 21.5. 22:00 na testovači. Predvádzanie projektov bude po prvom termíne skúšky v stredu 23.5. (t.j. začneme medzi 11:45 a 12:00 v H6). Ak vtedy nemôžete prísť, kontaktujte vyučujúce, dohodneme iný termín.
· Opravný/náhradný test bude v pondelok 28.5. o 10:00 v F1-108. V prípade záujmu sa prihláste v AISe.
· Na termíny skúšok sa zapisujte v AIS. Termíny: streda 23.5. (riadny), štvrtok 7.6. (riadny alebo 1. opravný), streda 20.6. (1. alebo 2. opravný) plus v prípade potreby ešte jeden termín v poslednom týždni skúškového. Prípadné konflikty nám dajte vedieť čím skôr. Ďalšie informácie na stránke Test a skúška.


Cvičenia 16

Z Programovanie
Prejsť na: navigácia, hľadanie

Jednoduché výnimky

Nižšie nájdete program z prednášky, ktorý načítava zo súboru číslo n a n čísel do poľa, pričom neexistenciu súboru a jeho zlý formát rieši výnimkami. Od užívateľa opakovane vypýta meno súboru, až kým sa mu nepodarí súbor prečítať.

  • Po načítaní čísel do poľa v metóde readArray overte metódou hasNext() triedy Scanner, že sa v súbore už nenachádzajú ďalšie čísla alebo iné nebiele znaky. Ak sa nachádzajú, hoďte tiež WrongFormatException.
  • Zmeňte program tak, aby WrongFormatException v konštruktore dostala aj podrobnejší popis chyby formátu, ktorá bude napríklad "Nepodarilo sa načítať počet prvkov n", alebo "Nepodarilo sa načítať prvok i", kde namiesto znaku i dosadíte príslušné poradové číslo prvku, kde nastala chyba. V metóde getMessage potom túto podrobnejšiu správu vráťte.
    • Návod: premennú i v metóde readArray zadefinujte už pred príkazom try a inicializujte na -1. V časti catch potom podľa aktuálnej hodnoty i viete zistiť, či sa for cyklus vôbec nezačal alebo na ktorom prvku zhavaroval.

Generická trieda Matrix

Naprogramujte generickú triedu Matrix, ktorá reprezentuje obdĺžnikovú maticu prvkov nejakého neznámeho typu E.

  • Prvky matice si v tejto triede uložte do premennej typu ArrayList<ArrayList<E>>, potrebujete si ešte udržiavať aj aktuálny počet riadkov a stĺpcov.
  • Napíšte konštruktor, ktorý vytvorí maticu zadaných rozmerov a vyplní ju zadaným prvkom typu E.
  • Napíšte metódy, ktoré do matice pridajú nový stĺpec a nový riadok, vyplnený zadaným prvkom typu E.
  • Napíšte metódu get, ktorá vráti prvok matice nachádzajúci sa na zadanom mieste
  • Napíšte metódu set, ktorá na zadané miesto v matici zapíše zadaný prvok typu E

Výnimky v triede Matrix

  • Čo sa stane, ak metódu get triedy Matrix zavoláte so súradnicami mimo rozsah matice?

Prepíšte metódy get a set tak, aby pri zlých súradniciach hádzali výnimku vašej vlastnej triedy MatrixIndexOutOfBoundsException.

  • Výnimka tejto triedy by v metóde getMessage mala vrátiť reťazec obsahujúci obidve súradnice, ako aj obidva rozmery matice.
  • Skúste dva spôsoby implementácie:
    • v prvom odchytávajte vzniknuté výnimky a nahraďte ich svojou výnimkou
    • v druhom otestujte vhodnosť indexov hneď na začiatku metódy a v prípade potreby vyhoďte vlastnú výnimku

Ešte Matrix, dedenie

Napíšte generickú triedu InfiniteMatrix, ktorá je podtriedou triedy Matrix a líši sa od nej v tom, že ak metóde get dáme súradnice mimo rozsah matice, vráti hodnotu null (a nevyhadzuje výnimku). Je to ako keby sme mali maticu nekonečnej veľkosti vyplnenú null-mi a v malom obdĺžniku s určitým počtom riadkov a stĺpcov máme nejaké uložené hodnoty, ktoré sa môžu líšiť od null.

Výnimky pre Scanner

Vytvorte triedu IntScanner, ktorá v konštruktore dostane meno súboru a okrem konštruktoru obsahuje public metódy hasNextInt, nextInt a close, ktoré robia zhruba to isté ako v triede Scanner. Avšak ak je v súbore nejaký reťazec, ktorý nie je možné interpretovať ako číslo, metóda nextInt vyhodí výnimku vašej novej triedy, ktorá v metóde getMessage vráti reťazec obsahujúci číslo riadku, na ktorom chyba nastala aj reťazec, ktorý nebolo možné ako číslo interpretovať. Trieda Scanner nám neumožňuje zistiť číslo riadku, preto budeme mať v tejto triede tri premenné:

  • aktuálne číslo riadku
  • premennú typu BufferedReader, v ktorej na začiatku otvoríme zadaný súbor a vždy keď treba, načítame z neho riadok, zvýšime počítadlo a vytvoríme novú inštanciu triedy Scanner, ktorá bude čítať čísla z toho riadku
  • premennú triedy Scanner

Zdrojový kód pre prvý príklad

package prog;

import java.io.*;
import java.util.Scanner;

class Prog {

    static class WrongFormatException extends Exception {

        private String filename;

        public WrongFormatException(String filename_) {
            filename = filename_;
        }

        @Override
        public String getMessage() {
            return "Zly format suboru " + filename;
        }
    }

    public static void main(String[] args) {

        boolean fileRead = false;
        Scanner s = new Scanner(System.in);
        int[] a = null;
        while (!fileRead) {
            try {
                System.out.print("Zadaj meno suboru: ");
                String filename = s.next();
                a = readArray(filename);
                fileRead = true;
                System.out.println("Dlzka pola je " + a.length);
            } catch (WrongFormatException e) {
                System.out.println(e.getMessage());
            } catch (FileNotFoundException e) {
                System.out.println("Subor nebol najdeny.");
            } catch (Throwable e) {
                System.out.println("Neocakavana chyba.");
                System.exit(1);
            }
        }

    }

    static int[] readArray(String filename)
            throws WrongFormatException, FileNotFoundException {
        Scanner s = null;
        int[] a = null;
        try {
            s = new Scanner(new File(filename));
            int n = s.nextInt();
            if (n < 0) {
                throw new WrongFormatException(filename);
            }
            a = new int[n];
            for (int i = 0; i < n; i++) {
                a[i] = s.nextInt();
            }
            return a;
        } catch (java.util.NoSuchElementException e) {
            throw new WrongFormatException(filename);
        } finally {
            if (s != null) {
                s.close();
            }
        }
    }
}