[英]Identity for BinaryOperator
我在Java8的UnaryOperator接口中看到了一段代碼,它對參數沒有任何作用並返回相同的值。
static <T> UnaryOperator<T> identity() {
return t -> t;
}
BinaryOperator有什么東西可以接受samekind的兩個參數並返回一個值
static <T> BinaryOperator<T> identity() {
return (t,t) -> t;
}
為什么我問這個問題是針對以下要求,
List<String> list = Arrays.asList("Abcd","Abcd");
Map<String,Integer> map = list.stream().collect(Collectors.toMap(str->str,
str->(Integer)str.length(),(t1,t2)->t1));
System.out.println(map.size());
在上面的代碼我不想為同一個鍵的兩個值做任何事情,我只想返回一個值,因為在我的情況下肯定值將是相同的。 由於我沒有使用t2值聲納投擲錯誤,所以我發現在java8中還有像BinaryOpertor的UnaryOperator.identity() 這樣的東西
你的問題沒有意義。 如果您要將建議的BinaryOperator.identity
方法粘貼到IDE中,您會立即看到它會抱怨標識符t
被聲明兩次。
要解決這個問題,我們需要為每個參數設置不同的標識符:
return (t, u) -> t;
現在我們可以清楚地看到這不是一個身份功能。 這是一個接受兩個參數並返回第一個參數的方法。 因此,最好的名稱就像getFirst
。
回答你關於JDK中是否有這樣的問題: 沒有 。 使用標識函數是一種常見的用例,因此為此定義方法很有用。 任意返回兩個第一個參數並不是一個常見的用例,並且有一個方法可以做到這一點。
T
表示它們具有相同的類型 ,而不是相同的值 ,而不是身份本身。
它只是意味着BinaryOperator
將用於相同的類型,但為不同的值提供identity
...這聽起來像foldLeft
或foldRight
或foldLeftIdentity/foldRightIdentity
,這是java沒有的。
您的代碼似乎可以改進為
List<String> list = Arrays.asList("Abcd", "Abcd");
Map<String, Integer> map = list.stream()
.collect(Collectors.toMap(Function.identity(), String::length, (a, b) -> a));
System.out.println(map.size());
或者可能對於你的用例我不想為同一個鍵的兩個值做任何事情,我只想返回一個值 ,你可以選擇隨機返回使用實現的任何值如下:
private static <T> BinaryOperator<T> any() {
return Math.random() < 0.5 ? ((x, y) -> x) : ((x, y) -> y);
}
然后在你的代碼中使用它
Map<String, Integer> map = list.stream()
.collect(Collectors.toMap(Function.identity(), String::length, any()));
感謝Holger,Eugene和Federico的建議,實際上可以使用的any
方法都有其他有效的實現:
private static <T> BinaryOperator<T> any() {
// suggested by Holger
return ThreadLocalRandom.current().nextBoolean() ? ((x, y) -> x) : ((x, y) -> y);
// suggested by Eugene
long nt = System.nanoTime();
((nt >>> 32) ^ nt) > 0 ? ((x, y) -> x) : ((x, y) -> y);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.