java 泛型 .net_Java泛型

标签:

上一篇博文java8函数式编程--收集器collector:(http://my.oschina.net/joshuashaw/blog/487322)讲得比较随性,并没有把源码一句一句拿出来分析,后来发现groupingBy方法最后有一个if-else分支用来返回不同类型的collector,一个是不需要特定finisher的,另一个需要使用下游收集器的finisher,今天细看源码,发现了几句神奇的代码,拿出来讲一讲。

先贴源码:

public static >

Collector groupingBy(Function super T, ? extends K> classifier,

Supplier mapFactory,

Collector super T, A, D> downstream) {

Supplier downstreamSupplier = downstream.supplier();

BiConsumer downstreamAccumulator = downstream.accumulator();

BiConsumer, T> accumulator = (m, t) -> {

K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");

A container = m.computeIfAbsent(key, k -> downstreamSupplier.get());

downstreamAccumulator.accept(container, t);

};

BinaryOperator> merger = Collectors.>mapMerger(downstream.combiner());

@SuppressWarnings("unchecked")

Supplier> mangledFactory = (Supplier>) mapFactory;

if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {

return new CollectorImpl<>(mangledFactory, accumulator, merger, CH_ID);

}

else {

/*---------------------------

----    --神奇的代码--   ------

-----------------------------

@SuppressWarnings("unchecked")

Function downstreamFinisher = (Function) downstream.finisher();

Function, M> finisher = intermediate -> {

intermediate.replaceAll((k, v) -> downstreamFinisher.apply(v));

@SuppressWarnings("unchecked")

M castResult = (M) intermediate;

return castResult;

};

-----------------------------

-----  ---神奇的代码-----  ----

--------------------------*/

return new CollectorImpl<>(mangledFactory, accumulator, merger, finisher, CH_NOID);

}

}

抽出来强调一下

@SuppressWarnings("unchecked")

Function downstreamFinisher = (Function) downstream.finisher();

Function, M> finisher = intermediate -> {

intermediate.replaceAll((k, v) -> downstreamFinisher.apply(v));

@SuppressWarnings("unchecked")

M castResult = (M) intermediate;

return castResult;

};

这里我们看到,类型为

(Function) downstream.finisher()

被强制类型转换成

(Function) downstreamFinisher

然后是

Map intermediate

被强制类型转换成

Map intermediate

我想,这都行?于是我写了两条语句

Fuction f1 = Integer::parse;

Fuction f2 = (Fuction) f1;

编译器报错。

但是为什么groupingBy方法里面可以这样写?于是我按照groupingBy方法写了一个测试类,代码如下:

import java.util.HashMap;

import java.util.Map;

import java.util.function.Function;

public class InterestingTest {

private Map Tmap = null;

private Map Vmap = null;

private Function Vf = null;

private Function Tf = null;

public InterestingTest(Map m,Function f){

Tmap = m;

Vf = f;

Tf = (Function) f;

Tmap.replaceAll((k,t)->Tf.apply(t));

Vmap = (Map) Tmap;

}

public Map getMap(){

return Vmap;

}

public static void main(String[] args) {

Map map = new HashMap<>();

map.put("1", 1);

map.put("2", 2);

map.put("3", 3);

map.put("4", 4);

Map newMap =

new InterestingTest(map,Integer::toBinaryString)

.getMap();

newMap.entrySet().stream()

.forEach(e->{System.out.println(e.getKey()+" "+e.getValue());});

}

}

代码只是报警告,一运行下来一点问题都没有,完美得出结果。

几天前刷知乎看到java实现不了真正的泛型,现在算是明白了。

其实,对于java泛型的实现,只是编译器在编译阶段帮助你进行类型转型,像Map类型,实际是保存你的对象的地址,对于Map来说,他只是存了Integer的地址,将Integer视为终极父类Object的子类,当你调用get(key)的时候,最后返回Object类型给你之前帮你强制类型转换成了Integer,就像:

put(key,IntegerObject){

this.object = IntegerObject;

}

get(key){

return (Integer) findCorrentObject;

}

所以从泛型的角度看,代码没有错误,但是会警告你这代码可能导致类型转换而出现的错误,于是我们可以看到

@SuppressWarnings("unchecked")

来去除警告。

但是,当你使用的是具体的类型时,编译器有职责给你报错,他认为你写的这行代码很有可能发生错误。

总结:都是兼容和初始开发人员省事而留下的问题啊。

标签:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值