簡體   English   中英

java stream返回參數化類的數組

[英]java stream return array of parameterized class

情況:

public class P {

    public static  Predicate<Double> isEqual(double value) {
        return p -> (Math.abs(p - value) <= 0.000001);
    }
}

public class Entity {   
    private double[] values;

    public double getValue(int index) {
        return values[index];
    }
}

未經檢查的轉化代碼:

public Attribute split(Entity[] examples) {
    @SuppressWarnings("unchecked") 
    Predicate<Double>[] pa = Arrays.stream(examples).map(e -> P.isEqual(e.getValue(a.index))).toArray(Predicate[]::new);
    return ...;
}

沒有未經檢查的轉換怎么解決這個問題?

我不能用這樣的:

public Attribute split(Entity[] examples) {
    Predicate<Double>[] pa = Arrays.stream(examples).map(e -> P.isEqual(e.getValue(a.index))).toArray(Predicate<Double>[]::new);
    return ...;
}

我實際上是要把我的評論作為答案,因為我發現這對研究很有意思,我現在非常自信。 答案取決於事實(正如@azurefrog所說),創建通用數組必須具有未經檢查的轉換。

請參閱: 如何在Java中創建通用數組?

Predicate<Double>[]::new相當於

IntFunction<Predicate<Double> []> predicateArrayMaker = (int size) -> new Predicate<Double>[size];

但是,如果沒有未經檢查的轉換,則無法創建通用數組。 例如,

Predicate<Double>[] predicateArray = new Predicate<Double>[10];

會有同樣的問題。

因此,未經檢查的轉換必須按照鏈接的答案中的說明進行。

沒有未經檢查的轉換就無法創建通用數組,因為創建通用數組本身就是一種不安全的操作。 由於不允許創建,因此您只能創建非泛型數組並執行未經檢查的轉換。

簡單地說,每一個可以在沒有任何警告的情況下實現后續堆污染的操作,都必須被認為是一種不安全的操作,要么自身產生警告,要么甚至會產生錯誤。 問題很容易證明:

Predicate<Double>[] p=/* someway to get the array*/;
Object[] array=p;
array[0]=(Predicate<Integer>)i -> i==0;

這種情況,其中一個數組的元素被聲明為Predicate<Double>類型,但其中一個實際上是Predicate<Integer> ,被稱為堆污染 既然兩者都將p賦值給Object[]類型的變量,並將Predicate<Integer>賦值給Object[]類型的數組元素,則是不生成警告的合法構造,創建數組本身必須被視為不安全的操作,必須生成警告或錯誤,以防止隨后的靜默堆污染。 否則,泛型無法聲稱提供編譯時安全性,即沒有未經檢查/不安全操作的代碼可確保不存在堆污染。

接受通用數組創建的唯一例外是在varargs的上下文中,但是為了獲得無警告代碼,即使用@SafeVarargs ,您必須接受基本限制,例如,您不能將數組分配給任何其他變量也不能返回它從方法,避免偷偷摸摸地引入上述問題。

所以底線是,你接受有一個未經檢查的操作或你使用List和“使用List ”意味着使用 List ,而不是嘗試通過List創建數組。 List和數組之間的根本區別在於,您不能將List<Predicate<Double>>分配給List<Predicate>List<Object> (沒有未經檢查的操作),因此它提供了Generics承諾的安全性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM