發表文章

目前顯示的是有「Functional Interface」標籤的文章

一段全都是蛋的簡易Java故事化教學例範程式碼

圖片
插圖: Alfredobear 因為聽到某熊聊到,在線上程式課程中學到陣列 (Array),而且把它形容成「儲蛋格」(egg storage tray),覺得很有趣,因此瞬間就給了我一個靈感,來寫一小段Java物件與串流的教學範例程式。 類別 (class) 是絕大多數物件導向程式語言 (Object-Oriented Programming Languages) 的基本單元,在物件導向的理論中,class代表了我們所要描述/解決的問題體系中某一實體或概念的抽象結果。 換句話說,因為我們不能把真實的蛋放進數位世界裡(就算做得到也變成另外一回事了),因此針對我們要解決的問題,把蛋「抽象化」(通常是抽取我們要的數據、狀態或是特徵),再加上一些和蛋有關的行為或是處理工作,就成了所謂的class的基本內容,基本的框架是長這樣: class Egg { // data field, status, characteristics... // behaviors, processing tasks... } 那麼想到陣列,也就是儲蛋格(因為太囉唆以下改稱蛋架egg rack),就會想到創建一個集合型態 List ,裡面專門放蛋,像是這樣: List<Egg> eggRack; 從這裡故事就開始了,我開始導入了串流界面相關的功能了……(聽到這會眼神死的人且慢) 首先,空的蛋架很無聊,又沒有蛋可以吃,身為蛋食愛好者當然是無法接受,因此我們需要一個無限供應蛋的串流(輸送帶),源頭裝上一個專門供蛋的供應器 ( Supplier<Egg> )。但大部份時候無限供蛋也可以釀成災難,所以我們需要指定數量限制,例如一百顆就好(!),然後在末端裝上一個集蛋器,這樣就可以做為裝滿蛋的蛋架: eggRack = Stream. generate (Egg:: new ) // 無限供蛋器 . limit ( 100 ) // 限制數量以免釀災 . collect (Collectors. toList ()); // 集蛋器 這裡 Egg::new 其實就是 Supplier 格式: () -> new Egg() 的簡寫,稱做method reference,...

泛型(generics)與函式界面(functional interface)做為強型別語言的一對翅膀

圖片
今天想來聊點泛型 (generics) 與 函式界面 (functional interface) 在強型別(strong-typed)語言中所扮演的重要角色。 身為Java愛好者、加上從事的工作和語義息息相關,不諱言地對於「強型別」的語言有一種執著。尤其在我們成長的年代,電腦並沒有像今天畫面包裝得美美的視窗防呆界面,對於機器的基底有多「固執」總有一種深刻的體會。若機器只接受整數 123 ,你一不小心給他字串 "123" ,就有可能當場「死」給你看。 而強型別語言的一板一眼有時確實也令人頭痛,就算可以運用多形 (polymorphism) 來增加語義上的彈性,仍然存在不少限制。例如我們可以用下面兩個同名函式來解決上面的問題,同時接受整數和字串: int inc ( int n) { return ++n; } int inc (String n) { return Integer. valueOf (n)+ 1 ; } 不過其實它們也就是兩個機器不會搞混的函式罷了,語義的一致性是給人類看的,機器認的是方法簽章(method signature),兩個函式實際上並沒有什麼關聯性。 當泛型和函式界面先後導入Java之後,強型別的優勢可說突然如虎添翼。為了不讓講古佔太大的篇幅,以下直接來研究一個最近實際遇到的例子。 最近因為武漢肺炎的關係,時常透過寫程式研究一些COVID-19的數據,茲舉以下這個存放某個國家某日數據的value object為例: class COVIDValue { String country; int recovered, cases, critical, active, deaths, todayCases, todayDeaths; double casesPerOneMillion, deathsPerOneMillion; // constructors, getters... } 它包含了三種不同型別( String 、 int 及 double )的資料欄位。假設我們寫了一個函式 list() 用來將存放在 List<COVIDValue> data 集合中的所有資料按某種順序列印出來,至於要依什麼順序,則由傳入的參數 k...