簡體   English   中英

枚舉字段為Null時ArrayList的元素。 正確的方法是什么?

[英]Elements of ArrayList in Enum field Null. What is the correct way to do this?

我的理論是,在初始化時首先強制第一個枚舉初始化第二個枚舉以構建第一個ArrayList,但是當它構建第二個枚舉的ArrayList而不是陷入邏輯循環時,它將值設置為Null 。

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        for (Ingredients ingredient: Ingredients.values()){
            Log.d("debug", ingredient.recipes.toString());
        }

        for (Recipes recipe: Recipes.values()){
            Log.d("debug",recipe.ingredients.toString());
        }
    }

    enum Ingredients {
        APPLE(new ArrayList<>(Arrays.asList(Recipes.APPLE_FRITTER))),
        BANANA(new ArrayList<>(Arrays.asList(Recipes.BANANA_FRITTER))),
        FLOUR(new ArrayList<>(Arrays.asList(Recipes.APPLE_FRITTER, Recipes.BANANA_FRITTER))),
        SUGAR(new ArrayList<>(Arrays.asList(Recipes.APPLE_FRITTER, Recipes.BANANA_FRITTER)));

        final ArrayList<Recipes> recipes;

        Ingredients(ArrayList<Recipes> products) {
            this.recipes = products;
        }
    }

    enum Recipes {
        APPLE_FRITTER(new ArrayList<>(Arrays.asList(Ingredients.APPLE, Ingredients.FLOUR, Ingredients.SUGAR))),
        BANANA_FRITTER(new ArrayList<>(Arrays.asList(Ingredients.BANANA, Ingredients.FLOUR, Ingredients.SUGAR)));

        final ArrayList<Ingredients> ingredients;

        Recipes(ArrayList<Ingredients> ingredients) {
            this.ingredients = ingredients;
        }
    }
}

這是logcat:

D/debug: [APPLE_FRITTER]
D/debug: [BANANA_FRITTER]
D/debug: [APPLE_FRITTER, BANANA_FRITTER]
D/debug: [APPLE_FRITTER, BANANA_FRITTER]
D/debug: [null, null, null]
D/debug: [null, null, null]

不幸的是,這段代碼只是一個較大項目的一個小示例,該項目取決於此工作,如果我需要有效地廢棄所有內容並重新開始,則只需要進行一些確認即可。

當然,這里缺少一些技巧,那太棒了。 無論哪種方式,謝謝您的見解。

編輯:發布此消息后不久,我想回應認輸,我想出了一個我認為是可以解決該問題的出色重構。 它不起作用,但是產生了另一個錯誤。 分享給有興趣的人:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        for (Ingredients ingredient: Ingredients.values()){
            Log.d("debug", ingredient.recipes.toString());
        }

        for (Recipes recipe: Recipes.values()){
            Log.d("debug",recipe.ingredients.toString());
        }
    }

    private final static ArrayList<Recipes> appleRecipes = new ArrayList<>(Arrays.asList(Recipes.APPLE_FRITTER));
    private final static ArrayList<Recipes> bananaRecipes = new ArrayList<>(Arrays.asList(Recipes.BANANA_FRITTER));
    private final static ArrayList<Recipes> flourRecipes = new ArrayList<>(Arrays.asList(Recipes.APPLE_FRITTER, Recipes.BANANA_FRITTER));
    private final static ArrayList<Recipes> sugarRecipes = new ArrayList<>(Arrays.asList(Recipes.APPLE_FRITTER, Recipes.BANANA_FRITTER));

    private final static ArrayList<Ingredients> appleFritterIngredients = new ArrayList<>(Arrays.asList(Ingredients.APPLE, Ingredients.FLOUR, Ingredients.SUGAR));
    private final static ArrayList<Ingredients> bananaFritterIngredients = new ArrayList<>(Arrays.asList(Ingredients.BANANA, Ingredients.FLOUR, Ingredients.SUGAR));

    enum Ingredients {
        APPLE(appleRecipes),
        BANANA(bananaRecipes),
        FLOUR(flourRecipes),
        SUGAR(sugarRecipes);

        final ArrayList<Recipes> recipes;

        Ingredients(ArrayList<Recipes> products) {
            this.recipes = products;
        }
    }

    enum Recipes {
        APPLE_FRITTER(appleFritterIngredients),
        BANANA_FRITTER(bananaFritterIngredients);

        final ArrayList<Ingredients> ingredients;

        Recipes(ArrayList<Ingredients> ingredients) {
            this.ingredients = ingredients;
        }
    }
}

和relevent logcat:

D/debug: [APPLE_FRITTER]
D/debug: [BANANA_FRITTER]
D/debug: [APPLE_FRITTER, BANANA_FRITTER]
D/debug: [APPLE_FRITTER, BANANA_FRITTER]
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.util.ArrayList.toString()' on a null object reference

問題是您有兩個枚舉在其構造函數中相互引用 ,這是一個循環引用。 您可以使用setter初始化來解決此問題。

免費提示: Arrays.asList返回新的ArrayList ,因此您無需再次將其包裝在新的ArrayList中 =)

enum Ingredients {
    APPLE,
    BANANA,
    FLOUR,
    SUGAR;

    static{
        APPLE.setRecipes(Arrays.asList(Recipes.APPLE_FRITTER));
        BANANA.setRecipes(Arrays.asList(Recipes.BANANA_FRITTER));
        FLOUR.setRecipes(Arrays.asList(Recipes.APPLE_FRITTER, Recipes.BANANA_FRITTER));
        SUGAR.setRecipes(Arrays.asList(Recipes.APPLE_FRITTER, Recipes.BANANA_FRITTER));
    }

    List<Recipes> recipes;

    private void setRecipes(List<Recipes> products){
        this.recipes = products;
    }

}

enum Recipes {
    APPLE_FRITTER,
    BANANA_FRITTER;

    static{
        APPLE_FRITTER.setIngredients(Arrays.asList(Ingredients.APPLE, Ingredients.FLOUR, Ingredients.SUGAR));
        BANANA_FRITTER.setIngredients(Arrays.asList(Ingredients.BANANA, Ingredients.FLOUR, Ingredients.SUGAR));
    }

    List<Ingredients> ingredients;

    private void setIngredients(List<Ingredients> ingredients) {
        this.ingredients = ingredients;
    }

}

Java Classloader是JRE的一部分,該JRE將Java類動態地加載到JVM中。 通常,僅按需加載類。

JVM何時開始類加載Ingredients 它在Ingredients.APPLE的構造函數中看到Recipes.APPLE_FRITTER ,因此開始類加載Recipes 它在Recipes.APPLE_FRITTER的構造函數中看到Ingredients.APPLEIngredients.FLOURIngredients.SUGAR引用,但我們仍在Ingredients.APPLE的構造函數中,因此Ingredients.APPLEIngredients.FLOURIngredients.SUGAR此處為null點,因此Recipes.APPLE_FRITTER的構造函數將所有項目獲取為null。

對不起,英語不好。 :)

暫無
暫無

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

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