将 if 字符串语句转换为 switch 字符串语句

Posted

技术标签:

【中文标题】将 if 字符串语句转换为 switch 字符串语句【英文标题】:Converting if string statements to switch string statements 【发布时间】:2015-09-30 12:37:31 【问题描述】:

我个人觉得使用和阅读 switch case 场景更容易。有谁知道我的列表视图的代码可以更改为什么,以便它在字符串上使用 switch 语句而不是 if 语句?我已根据需要将编译器更改为 1.7。

@Override
    public void onActivityCreated(Bundle savedInstanceState) 
        View v = getView();

        if (getActivity().findViewById(R.id.detail_container) != null) 
            mTwoPane = true;
         else 
            mTwoPane = false;
        

        ListView lv = (ListView)v.findViewById(android.R.id.list);
        lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() 



@Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
                // get the adapter, then get the name from the adapter at that position
        WorldListAdapter adapter = (WorldListAdapter) parent.getAdapter();
        String country = adapter.getItem(position);

                if (mTwoPane) 
            setItemNormal();
            View rowView = view;
            setItemSelected(rowView);

            Fragment newFragment;
            if (country.equals(view.getResources().getString(R.string.africa))) 
                newFragment = new FragmentAfrica();
             else if (country.equals(view.getResources().getString(R.string.asia))) 
                newFragment = new FragmentAsia();
             else if (country.equals(view.getResources().getString(R.string.europe))) 
                newFragment = new FragmentEurope();
             else 
                newFragment = new FragmentAfrica();
            
            WorldActivity activity = (WorldActivity) view.getContext();
            FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
            transaction.replace(R.id.detail_container, newFragment);
            transaction.commit();
         else 
            Intent intent;
            if (country.equals(view.getResources().getString(R.string.africa))) 
                intent = new Intent(getActivity(), AfricaActivity.class);
             else if (country.equals(view.getResources().getString(R.string.asia))) 
                intent = new Intent(getActivity(), AsiaActivity.class);
             else if (country.equals(view.getResources().getString(R.string.europe))) 
                intent = new Intent(getActivity(), EuropeActivity.class);
             else 
                intent = new Intent(getActivity(), AfricaActivity.class);
            
            startActivity(intent);
        
    

            public void setItemSelected(View view) 
                View rowView = view;
                view.setBackgroundColor(Color.parseColor("#1C3F96"));

                TextView tv0 = (TextView) rowView.findViewById(R.id.country);
                tv0.setTextColor(Color.parseColor("#FFFFFF"));

                TextView tv1 = (TextView) rowView.findViewById(R.id.country_description);
                tv1.setTextColor(Color.parseColor("#FFFFFF"));
            

            public void setItemNormal() 
                for (int i = 0; i < getListView().getChildCount(); i++) 
                    View v = getListView().getChildAt(i);
                    v.setBackgroundColor(Color.TRANSPARENT);

                    TextView tv0 = ((TextView) v.findViewById(R.id.country));
                    tv0.setTextColor(Color.WHITE);

                    TextView tv1 = ((TextView) v.findViewById(R.id.country_description));
                    tv1.setTextColor(Color.parseColor("#B5B5B5"));
                
            
        );

        super.onActivityCreated(savedInstanceState);
    

【问题讨论】:

我认为这个问题属于代码审查 如果switch 语句不是最佳解决方案怎么办? 我建议在多个级别上进行分支,因为在您的示例中,最好使用处理每组 if/else 部分的方法(而不是将它们全部组合成一个复杂的 switch 语句)... ,尽可能消除 if/else 并更喜欢工厂模式 我认为这不适合措辞上的代码审查。听起来 OP 正在尝试更改其代码的功能。一旦代码按预期运行,他们欢迎将其发布在 CR 上以供同行评审。 @Phrancis 不,OP 并没有要求更改功能,而是要求更改功能(ifswitch) - 我认为这将成为代码审查的主题,但是我更希望看到完整上下文的完整方法(不匹配的大括号表示一个块被切断),以便更好地允许审阅者comment on any and all facets of the code。我还建议让缩进看起来与 OP 在他们的 IDE 中完全一样。 【参考方案1】:

java 8 支持带有String的switch case

 @Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
    // get the adapter, then get the name from the adapter at that position
    WorldListAdapter adapter = (WorldListAdapter) parent.getAdapter();
    String country = adapter.getItem(position);

    if (mTwoPane) 
        setItemNormal();
        View rowView = view;
        setItemSelected(rowView);

        Fragment newFragment;
        switch (country.toLowerCase()) 
            case "africa":
                newFragment = new FragmentAfrica();
                break;
            case "asia":
                newFragment = new FragmentAsia();
                break;
            case "europe":
                newFragment = new FragmentEurope();
                break;
            default:
                newFragment = new FragmentAfrica();
        
        WorldActivity activity = (WorldActivity) view.getContext();
        FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.detail_container, newFragment);
        transaction.commit();
     else 
        Intent intent;
        switch (country.toLowerCase()) 
            case "africa":
                intent = new Intent(getActivity(), AfricaActivity.class);
                break;
            case "asia":
                intent = new Intent(getActivity(), AsiaActivity.class);
                break;
            case "europe":
                intent = new Intent(getActivity(), EuropeActivity.class);
                break;
            default:
                intent = new Intent(getActivity(), AfricaActivity.class);
        

        startActivity(intent);
    

           you can replace the literals `africa`,`asia`,`europe` with anything you want

【讨论】:

酷。虽然为什么那里有default: 因为在你的if-else-if 阶梯中,如果没有一个String 匹配你会用FragmentAfrica 初始化newFragment 我认为这是一个默认情况,这就是我添加它的原因。跨度> 如何使用字符串而不是硬编码? 我们使用switch-case 当我们修复了处理选项时,如果您正在考虑替换文字,即。 'asia','europe' 等带有一个变量,你基本上是在使用 'switch-case` 实现 'if-else' 我想通过硬编码你正在处理这些案例,对吧?【参考方案2】:

改为创建和使用工厂方法..

Fragment newFragment = FragmentFactory.createInstance(country, view);
...            
Intent intent = IntentFactory.createInstance(country, view);

这样,您可以在工厂类中添加新类型的片段和意图,但在客户端类中保留通用类型。这种方式更易于维护和扩展

请考虑这篇文章以了解有关此主题的另一篇文章Simple Factory vs Factory Method: Switch statement in factory vs. client

这是您案例的一个可能的工厂示例

public class FragmentFactory 

    public static Fragment getInstance(String country, View view) 
        Fragment newFragment = null;

        if (country.equals(view.getResources().getString(R.string.africa))) 
            newFragment = new FragmentAfrica();
         
        else if (country.equals(view.getResources().getString(R.string.asia))) 
            newFragment = new FragmentAsia();
         
        else 
            if (country.equals(view.getResources().getString(R.string.europe))) 
                newFragment = new FragmentEurope();
            
         
        return  newFragment;       
    

你可以把它当成开关试试

public static Fragment getInstance(String country, View view, ) 
    Fragment newFragment = null;

    switch (country.toLowerCase()) 

        case view.getResources().getString("africa"):
            newFragment = new FragmentAfrica();
            break;

        case view.getResources().getString("asia"):
            newFragment = new FragmentAsia();
            break;

        case view.getResources().getString("europe"):
            newFragment = new FragmentEurope();
            break;
                   
    return newFragment;

【讨论】:

您能否编辑答案以显示字符串资源的 switch case senarios 因为我想看看你会怎么做。

以上是关于将 if 字符串语句转换为 switch 字符串语句的主要内容,如果未能解决你的问题,请参考以下文章

No.6 流程控制的陷阱

Java的语句类型字符转换及字符串用法

为什么我不能将String转换为char并直接在Switch Statement中使用?

如何在JavaScript中将IF转换为SWITCH语句?

在 Swift 中将 switch 转换为 if else

switch多分支语句