繁体   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