2017-12-13 1 views
0

Wie kann ich eine ArrayList in eine generische Sammlung umwandeln? Ich habe das Problem in "SearchListener" mit "< ----------- Das funktioniert nicht !!!!"Cast ArrayList zu einer generischen abstrakten Sammlung

Ich lese über Class.cast (o), aber ich verstehe nicht, wie man es hier anwendet.

public abstract class MyTufinCollection<T> extends AbstractCollection<T> implements ListModel<String>{ 

}

public class SearchListener<T,C extends MyTufinCollection<T>> implements DocumentListener{ 

private JList jlist; 
private C staticCollectionOfTypeT; 
private List<Predicate<T>> predicateList = new ArrayList<>(); 
//get the String fields, and build Predicate from them.. add to predicateList. 



public SearchListener(JList jlist, List<Predicate<T>> predicateList, C collection) {   
    this.jlist = jlist; 
    this.staticCollectionOfTypeT=collection; 
    this.predicateList=predicateList; 
} 

@Override 
public void insertUpdate(DocumentEvent de) { 
    filter(); 
} 

@Override 
public void removeUpdate(DocumentEvent de) { 
    filter(); 
} 

@Override 
public void changedUpdate(DocumentEvent de) { 
    filter(); 
} 

private void filter() { 
    jlist.setModel((ListModel)staticCollectionOfTypeT); 
    C items = (C) jlist.getModel(); 

    Stream<T> itemStream = items.stream().filter(x ->{ 
     Stream<Predicate<T>> predicateStream= predicateList.stream(); 
     return predicateStream.map(predicate -> predicate.test(x)).reduce((a,b)->a && b).get(); 
    }); 
    ArrayList<T> collect = itemStream.collect(Collectors.toCollection(ArrayList::new)); 
    C name = (C)collect; // <-----------This Doesn't work!!!! 
    jlist.setModel((ListModel)name); 
} 

}

+1

Und warum sollte es funktionieren? –

+1

Wie kann ich das machen?Erstellen Sie eine neue MyTufinCollection() -Komfortklasse und verwenden Sie Collectors.toCollection (new MyTufinCollection() {...})? Oder gibt es einen besseren Weg? –

Antwort

0

Casting bedeutet nicht transformierende A in B. Es bedeutet nur Reduzierung der Ansicht.

Also, wenn Sie eine A haben und diese A ist auch eine B, zum Beispiel, weil es davon ausgeht. Dann können Sie die Ansicht zu diesem A reduzieren, indem Sie es auf B werfen. Zum Beispiel eine List erstreckt sich von Collection, so können Sie es auf Collection werfen. Aber ein String erstreckt sich nicht von Collection, Sie können es nicht übertragen.

In Ihrem Fall versuchen Sie, eine ArrayList auf eine C zu werfen, aber C extends MyTufinCollection<T>. ArrayList erstreckt sich davon nicht. Es ist wie der Versuch, eine ArrayList zu einer HashSet zu werfen, beide sind Collection s, aber es funktioniert aus offensichtlichen Gründen nicht.

Zum Beispiel MyTufinCollection hat wahrscheinlich einige Sachen, die ArrayList nicht hat, wie sollte Java automatisch bestimmen, was zu tun ist. Es kann nicht, Casting wird nicht funktionieren. Sie müssen explizit eine Konvertierungsmethode geben.

Der Begriff ist das is-a Prinzip. Sie können mehr über in JLS§5.5.1 Gießen lesen:

Wenn S (Quelle) ist eine Klasse, Typ:

Wenn T (Ziel) ist eine Klasse-Typ, dann entweder |S| <: |T| oder |T| <: |S|.
Sonst, ein Kompilierungsfehler tritt auf.

Außerdem, wenn es existiert einen übergeordneten Typen X von T, und einen übergeordneten Typ Y von S, so daß sowohl X und Y sind beweisbar unterschiedliche parametrisierten Typen (§4.5), und dass die Löschungen von X und Y sind Der gleiche, ein Kompilierungsfehler tritt auf.

+0

Ja, aber ich kann kein neues C erstellen, weil es generisch ist. Wie überwindest du das? –

+0

Warum können Sie keine neuen Instanzen von 'C' erstellen? Sie wissen, dass es mindestens 'MyTufinCollection ' ist, so dass Sie alle von dieser Klasse bereitgestellten Methoden verwenden können. Ich meine, du wirst dich fragen müssen, wie aus einer 'ArrayList' eine' MyTufinCollection' werden kann. Bietet die 'MyTufinCollection' eine Art' add' Methode? Dann können Sie einfach die Elemente der 'ArrayList' hinzufügen. – Zabuza

Verwandte Themen