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")

來去除警告。

但是,當你使用的是具體的類型時,編譯器有職責給你報錯,他認為你寫的這行代碼很有可能發生錯誤。

總結:都是兼容和初始開發人員省事而留下的問題啊。

標簽:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/529532.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/529532.shtml
英文地址,請注明出處:http://en.pswp.cn/news/529532.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

卡法電子商務 java_javacard DES算法API使用示例

********** 2017年3月15日留言 ——關于java卡Applet系列csdn博文 *************貌似有不少人在看我寫的幾篇關于java卡applet的博文&#xff0c;也收到了一些評論指正博文錯誤&#xff0c;或者私信叫我發代碼文件過去。在此需要說明的是&#xff0c;java卡applet的這幾篇博文…

java http請求原理_淺談Spring Cloud zuul http請求轉發原理

spring cloud 網關&#xff0c;依賴于netflix 下的zuul 組件zuul 的流程是&#xff0c;自定義 了ZuulServletFilter和zuulServlet兩種方式&#xff0c;讓開發者可以去實現&#xff0c;并調用先來看下ZuulServletFilter的實現片段Overridepublic void doFilter(ServletRequest s…

java堆外內存溢出_JVM 案例 - 堆外內存導致的溢出錯誤

案例一個網站為了實現客戶端實時從服務端接收數據&#xff0c;使用了 CometD 1.1.1 作為服務端推送框架&#xff0c;服務器是 Jetty7.1.4&#xff0c;CPU i5&#xff0c;內存 4G&#xff0c;操作系統 32位Windows。服務端常常拋出內存溢出異常&#xff0c;管理員把堆開到最大(3…

java mail outlook_已啟用Outlook API郵件與郵箱用戶

一個非常微妙的問題&#xff0c;也許是特定的環境 . 我正在嘗試使用Outlook 2010 API從啟用郵件的用戶中識別郵箱用戶 . 我們在Notes to Exchange遷移期間使用Dell Quest遷移工具&#xff0c;它是一個流動的項目 . 仍處于原型階段&#xff0c;因此使用VB宏來最終將在C&#xff…

oracle java存儲過程返回值_java程序調用Oracle 存儲過程 獲取返回值(無返回,非結果集,結果集)...

java程序調用Oracle 存儲過程 獲取返回值(無返回&#xff0c;非結果集&#xff0c;結果集)oracle中procedure是不能有返回值的&#xff0c;要想返回值&#xff0c;就得有輸出參數&#xff0c;同樣要想返回記錄集&#xff0c;可以把游標類型作為輸出參數。下面是詳細情況說明&am…

mysql dump工具升級_MySQL數據庫升級

當前不少系統的數據庫依舊是MySQL5.6&#xff0c;由于MySQL5.7及MySQL8.0在性能及安全方面有著很大的提升&#xff0c;因此需要升級數據庫。本文通過邏輯方式、物理方式原地升級來介紹MySQL5.6 升級至MySQL5.7的方法&#xff0c;并介紹其使用場景。1. 邏輯方式升級邏輯方式升級…

java int 128 ==_為什么 Java Integer 中“128==128”為false,而”100==100“為true?

這是一個挺有意思的討論話題&#xff0c;讓我們用代碼說話吧!運行下面的代碼:Integer a 128, b 128;System.out.println(a b);Integer c 100, d 100;System.out.println(c d);你會得到:falsetrue基本知識&#xff1a;我們知道&#xff0c;如果兩個引用指向同一個對象&…

mysql課程表學時_Mysql 鞏固提升 (學生表_課程表_成績表_教師表)

方便Mysql 鞏固提升創建表并插入數據&#xff1a;-- ------------------------------ Table structure for student-- ----------------------------DROP TABLE IF EXISTS student;CREATE TABLE student (id int(11) NOT NULL AUTO_INCREMENT,sname varchar(32) DEFAULT NULL,s…

初始java_第一章__初始JAVA

1.java的三個發展方向&#xff1a;JAVASE(面向對象、API、JVM)、JAVAME(移動設備、游戲、通信)、JAVAEE(JSP、EJB、服務)2.開發JAVA的程序步驟&#xff1a;1.編寫源程序 2.編譯 3.運行3.JDKJRE開發工具下載java環境jdk 安裝并配置環境變量&#xff0c;.安裝直接下一步下一步直到…

python最常用的版本、也稱為classic_2021年中國大學《創新思維與創業》單元測試答案...

2021年中國大學《創新思維與創業》單元測試答案被人們稱為 “寒地水稻第一人”的是袁隆平答&#xff1a;錯地圖數據的基本特征包括答&#xff1a;時間屬性 空間定位屬性 地理屬性對賣方征稅導致商品價格上升答&#xff1a;√( )是在床榻上使用的一種矮形家具。答&#xff1a;炕…

java 泛型 繼承_java基礎之泛型的繼承

關于泛型的基本介紹和理解請參考以下幾篇文章&#xff0c;或查詢更多資料&#xff1a;本篇以簡單的List<>方式來進行說明。ArrayList繼承了List,ArrayList沒有繼承ListList>等價于List extends Object>請參考以下代碼&#xff1a;/*** author Ding Chengyun* 2014-…

appium java環境_Appium環境搭建(Windows版)

注&#xff1a;appium安裝到C盤&#xff0c;node.js安裝到C盤一、安裝node.js1、到官網下載node.js&#xff1a;https://nodejs.org/en/download/2、獲取到安裝文件后&#xff0c;直接雙擊安裝文件&#xff0c;根據程序的提示&#xff0c;完成nodejs的安裝。3、安裝完成后&…

ci mysql pdo_CI框架中pdo的使用方法

1、配置文件修改application/config文件夾下的database.php文件 $db[default] array(dsn > mysql:dbnameci_ecshop;host127.0.0.1,username > root,password > ,dbdriver > pdo,2、查詢操作$sql select * from aaa where id :id;$sql_array array(:id > …

ie11加載java插件_IE瀏覽器中ActiveX插件的使用

在某些行業的B/S應用系統中會不可避免的要用到ActiveX瀏覽器插件&#xff0c;而ActiveX插件只能在IE內核瀏覽器中運行&#xff0c;而常用的IE瀏覽器的版本眾多&#xff0c;從IE6到IE11&#xff0c;總共有6個版本&#xff0c;這就給開發的應用系統造成了不小的困擾&#xff1a;如…

netty java開發文檔_Netty簡明教學文檔

寫個簡單點&#xff0c;比較小白的文檔&#xff0c;言語比較接地氣Netty是什么&#xff1f;NIO的高層封裝&#xff0c;NIO很難寫&#xff0c;所以有了Netty&#xff0c;方便異步的操作service的主要代碼片段public void run() throws Exception {EventLoopGroup bossGroup new…

mysql 全局不重復_php uniqid() 通過MYSQL實現全局不重復的唯一ID

看了國外文章&#xff1a;https://jason.pureconcepts.net/2013/09/php-convert-uniqid-to-timestamp/ 不想寫&#xff50;&#xff48;&#xff50;腳本uniqid()處理&#xff0c;想到用mysql一次性把數據庫的ID改過來的方法&#xff0c;所以開始了以下研究方法一: 效率最高&…

java接口允許ajax訪問_服務允許AJAX請求,允許跨域請求

當工作時間&#xff0c;因為需要JS 進行AJAX請求&#xff0c;這時候存在跨域問題&#xff0c;當出現這種情況時&#xff0c;有多種方案解決比如使用JSONP&#xff0c;也有一種簡單的方式&#xff0c;就是在過濾器里面增加返回請求允許跨域head配置。代碼如下&#xff1a;/**** …

mysql的增_MySQL之增_insert-replace

MySQL增刪改查之增insert、replace一、INSERT語句帶有values子句的insert語句&#xff0c;用于數據的增加語法&#xff1a;INSERT [INTO] tbl_name[(col_name,...)]{VALUES | VALUE} (expr ,...),(...),...①用來把一個新行插入到表中②為和其它數據庫保持一致&#xff0c;不要…

python manager詳解_python 多進程共享全局變量之Manager()詳解

Manager支持的類型有list,dict,Namespace,Lock,RLock,Semaphore,BoundedSemaphore,Condition,Event,Queue,Value和Array。但當使用Manager處理list、dict等可變數據類型時&#xff0c;需要注意一個陷阱&#xff0c;即Manager對象無法監測到它引用的可變對象值的修改&#xff0c…

java 添加等待時間_Java中線程等待特定時間的最有效方法 - java

我知道這個問題here&#xff0c;但是我有一個稍微不同的問題。如果我希望自己通過各種Thread方法(而不是通過實用程序類或Quartz)手動編碼某個線程在特定時間的運行&#xff0c;那么最有效(就開銷而言)進行編碼。我考慮過:boolean wasInterrupted false;while (System.current…