简体   繁体   中英

Cast ArrayList to a Generic Abstract Collection

How do I cast an ArrayList to a Generic Collection? I have highlighted the problem in "SearchListener" with "<-----------This Doesn't work!!!!"

I'm reading about Class.cast(o) but I'm not understanding how to apply it here.

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);
}

}

Casting doesn't mean transforming A into B . It only means reducing the view .

So if you have an A and this A is also a B , for example because it extends from it. Then you can reduce the view to this A by casting it to B . For example a List extends from Collection , thus you can cast it to Collection . But a String does not extend from Collection , you can't cast it.

In your case you are trying to cast an ArrayList to a C , but C extends MyTufinCollection<T> . ArrayList doesn't extend from that. It is like trying to cast an ArrayList to a HashSet , both are Collection s but it doesn't work for obvious reasons.

For example MyTufinCollection problably has some stuff that ArrayList does not have, how should Java automatically determine what to do. It can't, casting won't work. You will need to explicitly give a conversion-method.

The term is the is-a principle. You can read more about casting in JLS§5.5.1 :

If S (source) is a class type:

If T (target) is a class type, then either |S| <: |T| |S| <: |T| , or |T| <: |S| |T| <: |S| .
Otherwise , a compile-time error occurs.

Furthermore, if there exists a supertype X of T , and a supertype Y of S , such that both X and Y are provably distinct parameterized types ( §4.5 ), and that the erasures of X and Y are the same , a compile-time error occurs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM