亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 Java 8 流的映射函數來執行長時間運行的任務

使用 Java 8 流的映射函數來執行長時間運行的任務

哈士奇WWW 2024-01-05 14:55:33
我有一個方法,它將(遠程文件的)URL 列表作為應該下載的參數。該方法返回一個其他類型的List(稱為Attachment),它實際上包含java File類型的屬性。對于本例,我使用 Java Stream API 迭代 URL 并在“map”函數中啟動下載,該函數實際上返回 Attachment 實例?,F在我的問題是:我是否濫用 Java Stream API 來做一些不該做的事情?喜歡將長時間運行的任務放入其中嗎?我應該只對輸入數據進行小操作嗎?我現在看到的唯一缺點是測試有點困難。private List<Attachment> download(List<URL> attachments) {        return attachments.stream().map(attachmentUrl -> {            try {                Attachment attachment = new Attachment();                File attachmentFile = new File(getFilename(attachment.getAttachmentId(), attachmentUrl));                FileUtils.copyURLToFile(                        attachmentUrl,                        attachmentFile,                        CONNECT_TIMEOUT,                        READ_TIMEOUT);                attachment.setAttachmentFile(attachmentFile);                return attachment;            } catch (IOException e) {                e.printStackTrace();                LOGGER.error(e.getLocalizedMessage());            }            return null;        }).filter(Objects::nonNull).collect(Collectors.toList());    }
查看完整描述

2 回答

?
ABOUTYOU

TA貢獻1812條經驗 獲得超5個贊

我認為考慮map其他函數結構(例如filter,reduce等)可能會有所幫助,而不是函數,而是語法。stream().map()是執行循環功能的語法for。問“我是否因為使用它執行的內容而濫用了該語法?” 那么就沒那么有意義了:for循環不關心每次迭代運行的任務需要多長時間,也不關心map。它對其應用的操作是不可知的,因此唯一的問題是您是否正確使用語法,即循環遍歷集合,從某物映射到某物。


在這種情況下,map語法在哪里,您想要的操作就完全沒問題了。但是,您的實現可能會被清理一些。


attachmentUrl -> {

? ? try {

? ? ? ? Attachment attachment = new Attachment();

? ? ? ? File attachmentFile = new File(getFilename(attachment.getAttachmentId(), attachmentUrl));

? ? ? ? FileUtils.copyURLToFile(

? ? ? ? ? ? ? ? attachmentUrl,

? ? ? ? ? ? ? ? attachmentFile,

? ? ? ? ? ? ? ? CONNECT_TIMEOUT,

? ? ? ? ? ? ? ? READ_TIMEOUT);

? ? ? ? attachment.setAttachmentFile(attachmentFile);

? ? ? ? return attachment;

? ? } catch (IOException e) {

? ? ? ? e.printStackTrace();

? ? ? ? LOGGER.error(e.getLocalizedMessage());

? ? }

? ? return null;

}

對于內聯 lambda 來說有點大map。一般來說,我傾向于對任何map需要大括號(即占用多行)的 lambda 持懷疑態度,盡管并不總是反對。我建議將此 lambda 重構為一個命名函數,并且可能是幾個函數,它們要么是嵌套的(map(this::A)然后A調用B),要么是由流操作串行使用map(this::A).map(this::B)。


[編輯:] 關于并行化您的stream:請記住,作為此方法的一部分,您所做的不僅僅是 CPU 處理 - 您似乎正在執行網絡 IO文件 IO。如果并行執行,您不僅會并行化 CPU 利用率,還會并行化網絡和磁盤使用率。如果網絡磁盤是主導因素,而不是 CPU,那么并行化可能不會給你帶來什么好處,而且可能會讓事情變得更糟。一般來說,更多的線程!=更快的網絡或磁盤讀/寫。



查看完整回答
反對 回復 2024-01-05
?
森欄

TA貢獻1810條經驗 獲得超5個贊

流是非常優雅的工具,可以以函數式編程方式處理數據,相同的輸入將導致相同的輸出,并且沒有副作用,這將使您的代碼不易出錯且更具可讀性。因此,無論輸入量有多大,在使用方面都不存在濫用情況。如果您希望處理大量數據,則可以使用并行流。但是,您的實現可以進行一些清理,不要將所有業務邏輯委托給單個映射操作,使其更細粒度并將邏輯分散到多個映射器中,您可以像任何變量一樣聲明映射器,并將映射器插入Function<URL, File> urlToFileMapper = url -> {...}到溪流,attachments.stream().map(urlToFileMapper).map(anotherDeclaredMapper)...



查看完整回答
反對 回復 2024-01-05
  • 2 回答
  • 0 關注
  • 180 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號