2011-07-19 12 views
23

Próbuję napisać ogólną metodę zwracania zawartości formularza Iterable w tablicy.Metoda wielokrotnego użytku do przekształcenia Iterable <T> na T []?

Oto co mam:

public class IterableHelp 
{ 
    public <T> T[] toArray(Iterable<T> elements) 
    { 
     ArrayList<T> arrayElements = new ArrayList<T>(); 
     for(T element : elements) 
     { 
      arrayElements.add(element); 
     } 

     return (T[])arrayElements.toArray(); 
    } 
} 

Ale ja dostaję ostrzeżenie kompilatora „Uwaga: ... \ IterableHelp.java używa operacji niesprawdzony lub niebezpieczne”

Jakieś myśli na temat innego podejścia, które pozwoli uniknąć takiego ostrzeżenia?

+2

Zakładam, że ostrzeżenie dotyczy tej ostatniej linii, w której przestawiasz tablicę na 'T []'? – MatrixFrog

+0

@MatrixFrog correct – Dejas

+2

Zobacz także Guava 'Iterables.toArray (Iterable , Class )' –

Odpowiedz

27

W Google Guava jest metoda Iterables.toArray.

Patrząc na the source, jest zdefiniowana jako:

/** 
    * Copies an iterable's elements into an array. 
    * 
    * @param iterable the iterable to copy 
    * @param type the type of the elements 
    * @return a newly-allocated array into which all the elements of the iterable 
    *  have been copied 
    */ 
    public static <T> T[] toArray(Iterable<? extends T> iterable, Class<T> type) { 
    Collection<? extends T> collection = toCollection(iterable); 
    T[] array = ObjectArrays.newArray(type, collection.size()); 
    return collection.toArray(array); 
    } 

Gdzie ObjectArrays.newArray ostatecznie deleguje do metody, która wygląda następująco:

/** 
    * Returns a new array of the given length with the specified component type. 
    * 
    * @param type the component type 
    * @param length the length of the new array 
    */ 
    @SuppressWarnings("unchecked") 
    static <T> T[] newArray(Class<T> type, int length) { 
    return (T[]) Array.newInstance(type, length); 
    } 

Wygląda więc na to nie ma sposobu, aby uniknąć @SuppressWarnings w całości, ale możesz i powinieneś przynajmniej ograniczyć to do najmniejszego możliwego zakresu.

Albo, jeszcze lepiej, po prostu użyj cudzej implementacji!

2

Nie ma sposobu, aby pozbyć się ostrzeżenia unchecked or unsafe operations lub tworzenia macierzy TypeSafe bez edytowania podpisu metody.

Zobacz ten bug report, aby poznać szczegóły.

Jednym ze sposobów jest przekazać w wstępnie przyznane tablicę typu T:

public class IterableHelp 
{ 
    public <T> T[] toArray(final T[] t, final Iterable<T> elements) 
    { 
     int i = 0; 
     for (final T element : elements) 
     { 
      t[i] = element; 
     } 
     return t; 
    } 
} 

ten pozbywa się ostrzeżenia unchecked or unsafe, ale również stawia ciężar na klasy wywołującego, aby utworzyć tablicę z poprawne granice, aby zacząć od rodzaju porażek celu twojej metody wygody.

Jeśli chcesz dynamicznie tworzyć tablicę TypeSafe, naprawdę nie możesz tego zrobić w sposób TypeSafe w Javie.

To działa i kompiluje, ale nie rozwiązuje problemu z niezaznaczonymi lub niebezpiecznymi numerami , po prostu przenosi go do innego miejsca. Musiałem dodać adnotację @SuppressWarnings, aby przestać narzekać na obsadę.

@SuppressWarnings({"unchecked"}) 
public class IterableHelp 
{ 
    public <T> T[] toArray(Class<T> t, Iterable<T> elements) 
    { 
     final ArrayList<T> arrayElements = new ArrayList<T>(); 
     for (T element : elements) 
     { 
      arrayElements.add(element); 
     } 
     final T[] ta = (T[]) Array.newInstance(t, arrayElements.size()); 
     return arrayElements.toArray(ta); 
    } 
} 
0

Masz większy problem niż niezaznaczone ostrzeżenie. W rzeczywistości wywoła wyjątek ClassCastException w środowisku wykonawczym, jeśli T jest czymkolwiek innym niż Object.

Spróbuj String[] foo = IterableHelp.toArray(new ArrayList<String>());

Mówiąc najprościej, ponieważ tablice zawierają typ składnika w czasie wykonywania, aby utworzyć właściwą T [] należy zdać w klasie komponentu jako kolejny argument (jako klasy T lub T [] samodzielnie lub jako obiekt T lub T []) i użyj odbicia, aby utworzyć macierz. Metoda Collection z, która przyjmuje argument, przyjmuje obiekt T [] z tego powodu.

Powiązane problemy