为什么泛型T不能用作classif 的返回类型T extends Class.
例:
public class Foo<T extends Bar> {
Bar[] array = new Bar[200];
Optional<T> forIndex(int index) {
return Optional.ofNullable(array[index]);
}
}
Run Code Online (Sandbox Code Playgroud)
T需要延长Bar哪个意味着T永远不会有铸造问题,或者我是否误解了这个?有人可以详细说明.
如果类型变量是通配符,那么该方法的返回类型是什么?
public class MyClass{ }
List<? extends MyClass> nms = new ArrayList<MyClass>();
nms.add(new MyClass()); //compilation error
MyClass n = nms.get(0); //compiles fine
Run Code Online (Sandbox Code Playgroud)
东西是返回类型get不是纯MyClass类型.Eclipse告诉我它CAP#2和add方法的参数在CAP#1哪里CAP#2是subtypeof MyClass,但MyClass不是subtypeof CAP#1?
所以,我对编译器捕获类型在类层次结构中的位置感兴趣?如果我们创造
public class MySubClass extends MyClass{ }
Run Code Online (Sandbox Code Playgroud)
将CAP#2是哪一个子类型MySubClass?
我使用cqengine进行集合索引:
Attribute<UtilizationEntry, LocalDate> startDateAttr = new SimpleAttribute<UtilizationEntry, LocalDate>() {
@Override
public LocalDate getValue(UtilizationEntry object, QueryOptions queryOptions) {
return object.getStartDate();
}
};
IndexedCollection<UtilizationEntry> entries = new ConcurrentIndexedCollection<>();
entries.addIndex(NavigableIndex.onAttribute(startDateAttr)); // compilation error in this line
Run Code Online (Sandbox Code Playgroud)
此代码未编译,因为:
Error:(61, 70) java: no suitable method found for onAttribute(com.googlecode.cqengine.attribute.Attribute<entities.UtilizationEntry,java.time.LocalDate>)
method com.googlecode.cqengine.index.navigable.NavigableIndex.<A,O>onAttribute(com.googlecode.cqengine.attribute.Attribute<O,A>) is not applicable
(inferred type does not conform to equality constraint(s)
inferred: java.time.chrono.ChronoLocalDate
equality constraints(s): java.time.chrono.ChronoLocalDate,java.time.LocalDate)
method com.googlecode.cqengine.index.navigable.NavigableIndex.<A,O>onAttribute(com.googlecode.cqengine.index.support.Factory<java.util.concurrent.ConcurrentNavigableMap<A,com.googlecode.cqengine.resultset.stored.StoredResultSet<O>>>,com.googlecode.cqengine.index.support.Factory<com.googlecode.cqengine.resultset.stored.StoredResultSet<O>>,com.googlecode.cqengine.attribute.Attribute<O,A>) is not applicable
(cannot infer type-variable(s) A,O
(actual and formal argument lists differ in length)) …Run Code Online (Sandbox Code Playgroud) 我正在尝试理解java通用的covariancy,我理解为什么
List<Number> list = new ArrayList<Integer>();
Integer = list.get(0);
Run Code Online (Sandbox Code Playgroud)
不允许使用float,因此不会将float放入列表中,从而导致问题.我相信类型擦除会将其编译为:
List list = new ArrayList();
Integer = (Integer) list.get(0);
Run Code Online (Sandbox Code Playgroud)
这是允许的:
List<? extends Number> list = new ArrayList<Integer>();
Integer = list.get(0);
Run Code Online (Sandbox Code Playgroud)
类型擦除后,这不会编译成同样的东西吗?通配符如何帮助编译器强制执行浮点数在保存整数时不会放入列表中?
一种Java reduce方法Stream:
<U> U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner);
Run Code Online (Sandbox Code Playgroud)
有助于根据流中对象的某些属性来减少流.
但是,我不清楚为什么accumulator不能更直接和服务于同一目的:
BiFunction<U, T, U> accumulator.
accumulator签名中的通配符提供了哪些额外的灵活性(以降低可读性为代价)?
java支持class Foo<T super X>,如果没有,为什么?
其中T是类型参数,X是类型.
在Java 8中,类java.util.Optional(javadoc)类提供"Maybe"Monad或Option Type的功能.
更直接:
public final class java.util.Optional <T> extends Object
容器对象,可能包含也可能不包含非null值.如果存在值,则isPresent()将返回true,get()将返回该值.
其中一种方法是:
<U>可选<U>地图(功能<?super T,?extends U> mapper)
如果存在值,则将提供的映射函数应用于该值,如果结果为非null,则返回描述结果的Optional.
问题是为什么map()在类型上使用类型通配符U.
我对类型通配符的理解很简单:
? super T从指定从该组由子类路径给定类型的一些Object到T(两者Object并T包括)联合在拉出任何subinterfacing路径上找到的组接口"作为sidedish"通过implements.
并? extends U简单地从扩展U(U包括)的类集合中指定一些类型.
所以可以写一下:
<U>可选<U>地图(功能<?super T,U> mapper)
没有丢失信息.
或不?
许多Java Stream接口方法在参数中使用下界通配符
例如
Stream<T> filter(Predicate<? super T> pred)
Run Code Online (Sandbox Code Playgroud)
和
void forEach(Consumer<? super T> action)
Run Code Online (Sandbox Code Playgroud)
Predicate<? super T>在Predicate<T>这里使用的好处是什么?
我知道,Predicate<? super T>可以将T和超级类型的谓词对象作为参数传递给方法,但是我无法想到在特定类型上需要超级类型的谓词的情况?
例如,如果我有一个Stream<Integer>i,则可以将Predicate<Integer>, Predicate<Number>, and Predicate<Object>对象作为参数传递给它的filter方法,但是为什么有人会传递Predicate<Object>over Predicate<Integer>?在这里
使用的好处是<? super T>什么?
我很难理解以下有关两个Predicate对象的代码。第一个使用下界通配符,第二个使用上界通配符。
Predicate<? super String> p1 = s -> s.startsWith("a"); // why can I call startsWith()?
Predicate<? extends String> p2 = s -> s.startsWith("a");
p1.test("a"); // works
p2.test("a"); // doesn't work (why?)
Run Code Online (Sandbox Code Playgroud)
我不明白的p1是,为什么可以从类中调用方法String,例如startsWith()?为什么我只能将String对象传递到p1.test(),我希望也可以调用Number和Object对象。
就像p1我想的p2那样,但事实并非如此。我什String至无法将对象传递到中p2.test()。这对我来说没有任何意义,因为我们希望有一个继承自String(包括String)的对象。
我认为这可能与以下事实有关:我们指定引用类型而不是对象本身的类型。但是该对象使用什么类型?
我有兴趣编写一个通用的 split 方法,它可以像这样调用:
List<String> names = splitField("John, Nate, Larry", String::valueOf);
List<Integer> ages = splitField("35, 23, 48", Integer::valueOf);
Run Code Online (Sandbox Code Playgroud)
这是我的实现:
private <T, R> List<R> splitField(String stringWithComma, Function<T, R> valueOf) {
List<R> elements = new ArrayList<>();
if (stringWithComma != null && !stringWithComma.isEmpty()) {
elements = Arrays.stream(stringWithComma.split(","))
.map(valueOf)
.collect(Collectors.toList());
}
return elements;
}
Run Code Online (Sandbox Code Playgroud)
它没有建立,我在这里错过了什么?
谢谢!
编辑 1:
此实现构建并运行良好,使用 调用String::valueOf,但在调用时抛出异常Integer::valueOf
private <R> List<R> splitField(String elementsWithComma, Function<String, R> valueOf) {
List<R> elements = new ArrayList<>();
if (elementsWithComma != null && !elementsWithComma.isEmpty()) {
elements …Run Code Online (Sandbox Code Playgroud) java ×10
generics ×8
java-8 ×2
java-stream ×2
covariance ×1
cqengine ×1
list ×1
type-erasure ×1