Method unmodifiablelist() cannot be applied to given type

Newbie :

I am trying to compile a former co-worker's code but it says that the method unmodifiableList() can not be applied to a given type. The code in Eclipse does not show any error. But it still does not let me compile it. What could be the error?

package framework.interview.demographics;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.xmlbeans.impl.xb.xsdschema.Public;
import framework.data.people.NonReference;
import framework.data.people.people;

public class schedualData {

    private final List<people> schedual;

    private schedualData(List<people> schedual) {
            this.schedual = Objects.requireNonNull(schedual);
    }

    public static schedualData getSchedualData(List<people> schedual) {
        if(schedual.size() < 1)
            throw new IllegalArgumentException("schedual must   contain at least one people");

        if(Stream.of(schedual).filter(people -> (!(people instanceof NonReference))).count() != 1)
            throw new IllegalArgumentException("There must be one and only one Reference between"   + "People, number, and Review");

        return new schedualData(schedual);
    }

        //****** Getters ******\\
       public people getReference() {
          return schedual.stream()
         .filter(people -> !(people instanceof NonReference))
         .toArray(people[]::new)[0];
    }   

    public List<NonReference> getNonReferenceschedual() {
        //This is where the error is showing. 
        return Collections
               .unmodifiableList(schedual.stream()
               .filter(NonReference.class::isInstance)
               .map(x -> (NonReference) x)
               .collect(Collectors.toCollection     (ArrayList<NonReference>::new)));
      }

    public List<people> getFullschedual() {
        return Collections.unmodifiableList(schedual);
    }  

   public int size() {
       return schedual.size();
   }
}

This is the error log/information that eclipse prints once I compile the application:

[INFO] BUILD FAILURE

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-      plugin:3.6.1:compile (default-compile) on project 
         AutomationTesting: Compilation failure: Compilation failure: 
[ERROR] /C:/Users/Newbie/eclipse-   workspace/automationTesting/Data.java:[42,35] method unmodifiableList in    class java.util.
          Collections cannot be applied to given types;
[ERROR]   required: java.util.List<? extends T>
[ERROR]   found: java.util.Collection<framework.data.people.NonReference>
[ERROR]   reason: inferred type does not conform to upper bound(s)
[ERROR]     inferred: java.lang.Object&java.util.List<? extends   java.lang.Object>&java.util.Collection<framework.data.people.NonReference>
[ERROR]     upper bound(s):   java.util.Collection<framework.data.people.NonReference>,java.util.List<?  extends java.lang.Object>,java.lang.
              ObjectCompilation failure: Compilation failure: 
[ERROR] /C:/Users/Newbie/eclipse-workspace/automationTesting/Data.java:  
[42,35] method unmodifiableList in class java.util.Collections 
        cannot be applied to given types;
[ERROR]   required: java.util.List<? extends T>
[ERROR]   found:    java.util.Collection<framework.data.people.NonReference>
[ERROR]   reason: inferred type does not conform to upper bound(s)
[ERROR]     inferred: java.lang.Object&java.util.List<? extends   java.lang.Object>&java.util.Collection<framework.data.people.NonReference>
[ERROR]     upper bound(s):  java.util.Collection<framework.data.people.NonReference>,java.util.List<? extends java.lang.Object>,java.lang.Object
Andrew Tobilko :

You need to explicitly declare generic type parameters. For some reason*, it can't be inferred.

return Collections.<NonReference>unmodifiableList(schedual.stream()
                                        .filter(NonReference.class::isInstance)
                                        .map(NonReference.class::cast)
                                        .collect(Collectors.toCollection(ArrayList::new)));

or

return Collections.unmodifiableList(schedual.stream()
                                        .filter(NonReference.class::isInstance)
                                        .map(NonReference.class::cast)
                                        .collect(Collectors.<NonReference, List<NonReference>>toCollection(ArrayList::new)));

or

ArrayList<NonReference> result = schedual.stream()
    .filter(NonReference.class::isInstance)
    .map(NonReference.class::cast)
    .collect(Collectors.toCollection(ArrayList::new));

return Collections.unmodifiableList(result);

Though, you could simply go with

return Collections.unmodifiableList(schedual.stream()
                                        .filter(NonReference.class::isInstance)
                                        .map(NonReference.class::cast)
                                        .collect(Collectors.toList()));

*The problem is that Collections.unmodifiableList determines the type for collect(Collectors.toCollection()), and not vice versa, as you were probably expecting.

You may help the compiler with type inference by stating exactly what you want. You say either what unmodifiableList should take or what .collect(Collectors.toCollection()) should return.

Any of the four snippets mentioned above will help you to resolve the issue.


x -> (NonReference) x can be replaced with NonReference.class::cast.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=126987&siteId=1