NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!
Avatar
ronep
Člen
Avatar
ronep:26.5.2017 22:34
public static <T> T[] toArray(Iterable<? extends T> list, Class<T> c) {
    int size = -1;
    if ((list instanceof Collection)) {
        Collection coll = (Collection) list;
        size = coll.size();
    }

    if (size < 0) {
        size = 0;

        for (T element : list) {
            size++;
        }
    }

    Object[] result = (Object[]) Array.newInstance(c, size);
    int i = 0;
    for (T element : list) {
        result[(i++)] = element;
    }
    return (T[]) result;
}

nechapem tomu co ma ta metoda vraciat a potrebujem ju opravit

hlavne nechapem tomu datovemu tipu tejto metodi

<T> T[]

ja to potrebujem opravit po niekom inom ja som to nepisal

tieto metodi ju pouzivaju:
1.

public FancyMessage translationReplacements(Iterable<FancyMessage> replacements) {
    return translationReplacements((FancyMessage[]) ArrayWrapper.toArray(replacements, FancyMessage.class));
}

2.

public FancyMessage formattedTooltip(Iterable<FancyMessage> lines) {
    return formattedTooltip((FancyMessage[]) ArrayWrapper.toArray(lines, FancyMessage.class));
}

3.

public FancyMessage tooltip(Iterable<String> lines) {
    tooltip((String[]) ArrayWrapper.toArray(lines, String.class));
    return this;
}

PS: ospravedlnujem sa za moju gramatiku

 
Odpovědět
26.5.2017 22:34
Avatar
Martin Dráb
Tvůrce
Avatar
Odpovídá na ronep
Martin Dráb:26.5.2017 23:08

Cílem té metody je převést obsah libovolné instance třídy podporující iterování na pole objetků. Toto pole je vráceno. Jedná se o generickou metodu, která může pracovat nad lkontejnerem uchovávajícím objekty libovolného typu (při popisu metody je tento typ zván T). Výrazem <T> v hlavicčce metody právě říkáš, že se jedná o generický typ, který bude specifikován při konkrétním volání této metody (ať už explicitně či implicitně).

Prvním parametrem je kontejner, jehož data chceš prevést do pole. Musí to být objekt implementující rozhraní Iterable nad typem odvozeným z T (což zřejmě zahrnuje i samtoné T). Druhým parametrem je v podstatě typ reprezentující T jako třídu.

Metoda přitom řeší dva případy: pokud je kontejner kolekce, získá její velikost metodou size. Pokud se o kolekci nejedná, získá počet prvků v kontejneru jeho proiterováním.

Jakmile zná počet prvků, metoda vytvoří instanci pole, naplní jej prvky ze vstupního kontejneru a vrátí jej.

V případě všech tří tebou uváděných volání dochází k automatickému odvození typu T. Pokud by se ti to nelíbilo, můžeš jej specifikovat explicitně (toArray<Nazev­Typu>).

Více třeba zde
https://docs.oracle.com/…methods.html

P.S.
Proč se v metodě používá objects[] a ne třeba T[], mi je lehce záhadou (asi proto, že v Javě neprogramuji), ale na sémantiku to nemá vliv.

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
26.5.2017 23:08
2 + 2 = 5 for extremely large values of 2
Avatar
ronep
Člen
Avatar
ronep:26.5.2017 23:25

pls mozes visvetlit vsetky pojmi v tejto vete :
"Cílem té metody je převést obsah libovolné instance třídy podporující iterování na pole objetků."

 
Nahoru Odpovědět
26.5.2017 23:25
Avatar
Martin Dráb
Tvůrce
Avatar
Odpovídá na ronep
Martin Dráb:27.5.2017 0:21

To znamená, že ta metoda akceptuje cokoliv, přes co můžeš iterovat, tedy procházet jeho prvky jeden po druhém. Například zde

for (T element : list) {

se využívá faktu, že parametr list podporuje iterování. Do proměnné element se postupně vkládají jednotlivé prvky v list, dokud se nedojde na konec.

A iterování bude podporovat každá třída implementující rozhraní Iterable.

Nahoru Odpovědět
27.5.2017 0:21
2 + 2 = 5 for extremely large values of 2
Avatar
gcx11
Tvůrce
Avatar
Odpovídá na Martin Dráb
gcx11:27.5.2017 3:48

Protože generika v Javě jsou jenom syntaktický cukr. Překládají se na automatické přetypování mezi typem T a typem Object.

Tento řádek

Array.newInstance(c, size);

ve skutečnosti vrací Object, jelikož pochází z doby, kdy v Javě generika nebyla.

A nyní k tomu, co udělá použití T[] místo Object[]. Díky tomu, že za běhu generika téměř neexistují, tak jediná změna je, že se ušetří jedno přetypování proměnné result na Object[] na konci metody.

Kód poté, co ho upraví kompilátor:

public static void main(String[] args) {
    List list = Arrays.asList(new Integer[]{Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3)});
    Integer[] array = (Integer[]) toArray(list, Integer.class);
}

public static <T> T[] toArray(Iterable<? extends T> list, Class<T> c) {
    int size = -1;
    if(list instanceof Collection) {
        Collection coll = (Collection)list;
        size = coll.size();
    }

    if(size < 0) {
        size = 0;

        for(Iterator iter = list.iterator(); iter.hasNext(); ++size) {
            Object o = iter.next();
        }
    }

    Object[] result = (Object[])((Object[])Array.newInstance(c, size));
    int i = 0;

    Object element;
    for(Iterator iter2 = list.iterator(); iter2.hasNext(); result[i++] = element) {
        element = iter2.next();
    }
    // toto přetypování zmizí při přetypování result na T[] namísto Object[]
    // na řádku s Array.newInstance
    return (Object[])result;
}

Jak je vidět, tak se z metody nevrací nevrací pole generického typu, ale pole objektů a přetypování se provádí až v místě použití.

Editováno 27.5.2017 3:49
 
Nahoru Odpovědět
27.5.2017 3:48
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 5 zpráv z 5.