2016-05-03 48 views
2

我正在尋找一種更方便的方法來校驗可選值的相等性。檢查選項的平等的便捷方式

這是一個Oracle Blog post暗示什麼:在一些

Optional<USB> maybeUSB = ...; maybeUSB.filter(usb -> "3.0".equals(usb.getVersion()) 
        .ifPresent(() -> System.out.println("ok")); 

恕我直言,結果像

if (maybeUSB.filter(c -> "3.0".equals(c.getVersion())).isPresent()) { 
    ... 
} 

當然,這是怎樣的一個壞榜樣的,因爲它比較版本和USB本身不是實例但我認爲它應該仍然證明我的觀點。

這是真的,因爲它得到好處呢?

沒有

boolean presentAndEquals(Object) 

boolean deepEquals(Object) 

我在這裏失去了一些東西?

編輯:

我不是Optionals.equals那快樂的要麼。 我是否真的必須首先裝入一個對象才能立即取消裝箱並檢查相等性?

+0

不要過早優化。你要麼必須裝箱(你不知道費用),要麼測試'isPresent()'(你也不知道這個費用)。 'maybeFoo.equals(Optional.of(...))'是可讀的,所以使用它。 – slim

+0

我同意過早優化,但它更多的是關於代碼高爾夫比時間..談論Java權利;) –

+1

「我不高興」沒有什麼特別的'可選':它只是一個容器供參考。你會期望另一個碰巧包含'String'的類爲'new Frobnitz(「some string」)。equals(「some string」)'返回true嗎?簡潔有用的情況超過了明顯不正確的情況。 –

回答

10

您有很多選擇。

已經指出:

boolean isEqual = maybeFoo.equals(Optional.of(testFoo)); 

或者:

boolean isEqual = maybeFoo.isPresent() && maybeFoo.get().equals(testFoo); 

或者:

boolean isEqual = testFoo.equals(maybeFoo.orElse(null)); 

最後兩個確實有語義稍有不同:每個返回不同的值時maybeFoo空和testFoo爲空。目前尚不清楚哪個是正確的響應(我認爲這是沒有標準API方法的原因之一)。

你或許可以拿出別人,如果你閱讀Optional API文檔和應用一些思考。文檔中沒有什麼魔法。

更一般地,如果你撞到這往往足以讓它打擾你,你可能會與錯誤的理念接近Optional

正如我所看到的,Optional是關於確認某些東西並不總是存在,並且您需要(有時是詳細的)代碼來處理它。

這應該是例外。儘可能地嘗試創建變量不能爲空或Optional.empty()

在這種情況下,這是不可避免的,因爲你需要額外的代碼。

+0

只有第二種解決方案適合這個問題 - 如果兩個值都不存在,OP希望測試是錯誤的。 –

+0

目前尚不清楚OP在這種情況下是否想過他真正想要的東西。 – slim

+0

也許,但我認爲意圖已經在願望清單例子'布爾presentAndEquals(Object)' –

6

Optional直接實現equals方法:

if (maybeUSB.equals(Optional.ofNullable(testUSB))) { 
    ... 
} 

(你也可以使用Objects.equals而不是直接調用equals

編輯:

如果你想同時不存在是假的,你可以這樣做:

if (maybeUSB.equals(Optional.ofNullable(testUSB)) && maybeUSB.isPresent()) { 
    ... 
} 
+0

如果兩者都不存在,則OP要求結果爲假。編輯 –

+0

- 你可以在一個額外的子句中檢查值存在 – thecoop

+0

@HankD與之比較的值是一個值。所以情況「兩者都不存在」。根本不會發生。至於你的其他評論:'presentAndEquals'意味着一個值存在並等於另一個值。 – zeroflagL