如何在Java中更好地随机调用方法(避免重复相似代码行)?

huangapple go评论76阅读模式
英文:

How to better randomize method calls in Java (without repeating similar lines)?

问题

package com.delta.generics;

import android.app.Activity;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Bundle;
import android.service.dreams.DreamService;
import android.util.StringBuilderPrinter;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class GenericsActivity extends Activity {

    public TextView nameTextView = null;
    public TextView descriptionTextView = null;
    public RatingBar ratingView = null;
    public ImageView portraitView = null;
    public Button nextButton = null;

    private int currentSelection = 0;

    AdoptAdapter<Cat> catAdoptAdapter;
    AdoptAdapter<Dog> dogAdoptAdapter;

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

        nameTextView = (TextView) findViewById(R.id.nameTextView);
        descriptionTextView = (TextView) findViewById(R.id.descriptionTextView);
        ratingView = (RatingBar) findViewById(R.id.ratingView);
        portraitView = (ImageView) findViewById(R.id.portraitView);
        nextButton = (Button) findViewById(R.id.nextButton);
        nextButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showNext();
            }
        });

        catAdoptAdapter = new AdoptAdapter<Cat>(this, nameTextView, descriptionTextView, ratingView, portraitView);
        dogAdoptAdapter = new AdoptAdapter<Dog>(this, nameTextView, descriptionTextView, ratingView, portraitView);

        catAdoptAdapter.set(AdoptData.mCatList.get(0));
        dogAdoptAdapter.set(AdoptData.mDogList.get(0));
    }

    public void showNext(){
        int random = currentSelection;
        int animal_random = (int) (Math.random() * 2);
        
        while(random == currentSelection){
            if (animal_random == 0) {
                random = (int) (Math.random() * AdoptData.mCatList.size());
            } else {
                random = (int) (Math.random() * AdoptData.mDogList.size());
            }
        }
        
        currentSelection = random;
        
        if (animal_random == 0) {
            Cat c = AdoptData.mCatList.get(random);
            catAdoptAdapter.set(c);
        } else {
            Dog d = AdoptData.mDogList.get(random);
            dogAdoptAdapter.set(d);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.generics, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

The revised showNext() method has eliminated the repeated lines by checking the animal_random value and deciding whether to work with cats or dogs accordingly. This simplifies the code and avoids unnecessary duplication.

英文:

I have this file as an example of a Pet app for Android that showcases profiles of cats or dogs (courtesy of a Udemy course). this is the base file:

package com.delta.generics;
import android.app.Activity;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Bundle;
import android.service.dreams.DreamService;
import android.util.StringBuilderPrinter;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class GenericsActivity extends Activity {
public TextView nameTextView = null;
public TextView descriptionTextView = null;
public RatingBar ratingView = null;
public ImageView portraitView = null;
public Button nextButton = null;
private int currentSelection = 0;
//    CatAdapter catAdapter;
AdoptAdapter&lt;Cat&gt; catAdoptAdapter;
//    AdoptAdapter&lt;Dog&gt; dogAdoptAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_generics);
nameTextView = (TextView) findViewById(R.id.nameTextView);
descriptionTextView = (TextView) findViewById(R.id.descriptionTextView);
ratingView = (RatingBar) findViewById(R.id.ratingView);
portraitView = (ImageView) findViewById(R.id.portraitView);
nextButton = (Button) findViewById(R.id.nextButton);
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showNext();
}
});
//        commenting this out in favour of AdoptAdapter objects
//        catAdapter = new CatAdapter(this,nameTextView,descriptionTextView,ratingView,portraitView);
//        catAdapter.set(AdoptData.mCatList.get(0));
catAdoptAdapter = new AdoptAdapter&lt;Cat&gt;(this, nameTextView, descriptionTextView, ratingView, portraitView);
//        dogAdoptAdapter = new AdoptAdapter&lt;Dog&gt;(this, nameTextView, descriptionTextView, ratingView, portraitView);
catAdoptAdapter.set(AdoptData.mCatList.get(0));
//        dogAdoptAdapter.set(AdoptData.mDogList.get(0));
// mCatList and mDogList is an object already exists in AdoptData.java
}
public void showNext(){
int random = currentSelection;
int animal_random = 0;
animal_random = (int )(Math.random() * 2;
while(random == currentSelection){
//avoid same selection twice.
random = (int )(Math.random() * AdoptData.mCatList.size());
random = (int )(Math.random() * AdoptData.mDogList.size());
}
currentSelection = random;
Cat c = AdoptData.mCatList.get(random);
//        Dog d = AdoptData.mDogList.get(random);
//        commenting in favour of AdoptAdapter object
//        catAdapter.set(c);
catAdoptAdapter.set(c);
//        dogAdoptAdapter.set(d);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.generics, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}

如何在Java中更好地随机调用方法(避免重复相似代码行)?

The issue I see is that the way this is formatted, it can only either showcase Cat or Dog profiles, but not together, and I wanted to figure out a way of how to "mix" them so both Cats and Dogs shows up randomly when pressing the "Next" button. And so I figured within the context of Java and this file, I figured I can modify the showNext() method:

    public void showNext(){
int random = currentSelection;
int animal_random = 0;
animal_random = (int )(Math.random() * 2);
Log.e(&quot;animal_random&quot;, String.valueOf(animal_random));
switch(animal_random){
case 0:
while(random == currentSelection){
//avoid same selection twice.
random = (int )(Math.random() * AdoptData.mCatList.size());
}
currentSelection = random;
Cat c = AdoptData.mCatList.get(random);
catAdoptAdapter.set(c);
break;
case 1:
while(random == currentSelection){
//avoid same selection twice.
random = (int )(Math.random() * AdoptData.mDogList.size());
}
currentSelection = random;
Dog d = AdoptData.mDogList.get(random);
dogAdoptAdapter.set(d);
break;
}
}

But I feel like there are way too many "repeated lines" here. If this were in Python I would probably utilize the getAttribute() method to determine which method to use in the object based on a string match. However when I tried to use the supposed Java equivalent getMethod() i keep getting a java.lang.NoSuchMethodException error when i try to use it.

Is there a better way to go about this in Java...? Or would it require a complete restructure for this specific example?

答案1

得分: 1

一旦你从以下两个替代方案中选择了任何一个,只需更新你的代码的其余部分,你可能会在整个代码中看到较少的重复,因为动物们将在某个共同点上有交集。 如何在Java中更好地随机调用方法(避免重复相似代码行)?

接口方式

创建一个名为 Animal 的接口,使你能够访问给定情况下动物的共同特征,然后在你的 DogCat 类中实现该接口。你的问题中的代码可能主要涉及 Animal,除非你需要以某种方式明确区分 DogCat

这种方法的一个好处是,虽然接口将强制执行一个契约,但它也为你提供了余地,例如,如果你希望 Dog 类能够包含 Cat 不应该包含的内容。也许它已经实现了?

枚举方式

将你的 DogCat 类合并为一个名为 Animal 的类,其中包含一个名为 typeenum 字段或类似的内容。减少了类的数量(万岁?),但要注意的是,狗、猫以及你将来添加的任何其他动物都必须适应相同的数据结构。根据动物的实际类型有多少重要性和意义,这可能是个好主意,也可能不是个好主意。

英文:

Once you've picked any of the two alternatives below, just update the rest of your code and you'll probably see less duplication across the board since the animals will have a common ground somewhere. 如何在Java中更好地随机调用方法(避免重复相似代码行)?

The interface way

Create an Animal interface that gives you access to the common things for animals in your given case, and then implement the interface in both your Dog and your Cat class. Your code in question will probably mostly be talking about Animals instead, unless you explictly need to differentiate between a Dog or a Cat in some way.

One of the neat things about this approach is that while the interface will enforce a contract, it also gives you the wiggle room for if you example want the Dog class to be able to contain stuff that the Cat shouldn't. Maybe it already does?

The enum way

Consolidate your Dog and Cat classes into a single Animal class that carries an enum field called type or something like that. Less classes (hurray?), but with the caveat that the dogs, cats and whatever future animals you add kinda have to fit into the same data structure. Depending on how much weight and meaning the actual type of animal actually has, this may or may not be a really bad idea.

huangapple
  • 本文由 发表于 2020年7月26日 05:04:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/63093558.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定