【问题标题】:Method with more than 50 input variables?输入变量超过 50 个的方法?
【发布时间】:2013-02-27 10:31:12
【问题描述】:

我正在开发一个应用程序,现在遇到了一个小问题。让我解释一下这个应用程序的目的是什么:
- 有一个带有不同按钮的主菜单(比如说 16 个按钮)。 - 每次用户单击一个按钮时,它都会向数据库发送一个请求,并根据您单击的按钮显示不同结果的结果列表视图。
- 在数据库中,有一列带有“类别号”。 (实际上有 3 列带有 CatNumbers,但让我们保持简单)。
- 请求要求显示此类别编号等于某些值的所有元素(这些是我的方法的输入,称为“myVariableN”,通过 putExtra/getExtra 从 MainActivity 发送到 ListView 活动)。在我的 ListViewActivity 中显示结果:

private void displayListView() {
    Bundle bundle = getIntent().getExtras();
    String title = bundle.getString("title", "Choose here :");
    int myVariable1 = bundle.getInt("myVariable1", 500);
    int myVariable2 = bundle.getInt("myVariable2", 500);
    int myVariable3 = bundle.getInt("myVariable3", 500);
    int myVariable4 = bundle.getInt("myVariable4", 500);
    int myVariable5 = bundle.getInt("myVariable5", 500);
    int myVariable6 = bundle.getInt("myVariable6", 500);

所以我到目前为止是这样的:例如,如果您单击按钮 1,它会发送 6 个变量 (myVariable1, 2, 3 ... 6) 并要求显示所有元素“WHERE CatNumber IN (myVariable1, myVariable2 , ... myVariable6)。

public Cursor findPoiInTable(int myVariable1, int myVariable2,
        int myVariable3, int myVariable4, int myVariable5, int myVariable6) 
{
    String inInterval = "(?,?,?,?,?,?)";
    String where = COL_CAT1 + " IN " + inInterval + " OR " + COL_CAT2
            + " IN " + inInterval + " OR " + COL_CAT3 + " IN " + inInterval;
    String[] whereArgs = new String[3 * 6];

    for (int i = 0; i < 3; i++) 
    {
        whereArgs[6 * i] = Integer.toString(myVariable1);
        whereArgs[6 * i + 1] = Integer.toString(myVariable2);
        whereArgs[6 * i + 2] = Integer.toString(myVariable3);
        whereArgs[6 * i + 3] = Integer.toString(myVariable4);
        whereArgs[6 * i + 4] = Integer.toString(myVariable5);
        whereArgs[6 * i + 5] = Integer.toString(myVariable6);
    }
    Cursor c = myDatabase.query(DATABASE_TABLE, new String[] { KEY_ROWID,
            COL_NAME, COL_STREET}, where, whereArgs, null, null, null);
   return c; 
} 

问题是,在主菜单的这 16 个按钮中,有几个按钮需要从数据库中获取具有更大范围类别编号的数据。例如,类似“SELECT .... FROM.... WHERE CatNumber IN (myVariable1, myVariable2, ..... myVariable*50*)。
不幸的是,每个按钮的方法必须相同,无论输入变量是 2 个还是 50 个。

我觉得如果我这样做,我的方法会太重并且会减慢我的整个应用程序,因为在大多数情况下,即使请求应该找到 2 或 3 个 CatNumber,该方法也会为 50 个或更多输入定义,因此每次都必须进行整个计算。

我在想的是:
a/ 用 IF 语句修改我的方法,例如,如果 IF 少于...假设发送了 6 个变量,它将仅使用 6 个 myVariable 输入创建轻量级方法,否则,它将运行具有 50 个输入的重型方法。所以heavy方法只会在少数情况下使用,错误的是即使只有7个输入,它也会运行heavy方法。或者以同样的想法,我可以发送一个通过 putExtra 发送的布尔值,并设置为 TRUE(用于使用 light 方法)和 FALSE(然后它将使用 heavy 方法)。
b/ 将值默认设置为 500(如我的代码中所做的那样),因此只有特定的 myVariables 的值不同于 500。然后我的问题是:是否可以定义一个具有 50 个输入的方法并让它只使用值与某个数字不同的输入,所以方法并不总是太重而无法运行?例如在上面的代码中使用方法,是否可以说只看对于两个变量,如果其他四个等于 500(myVariable1 和 myVariable2,而不是所有变量,即使为其余变量定义了整个方法?)。
提前致谢!

【问题讨论】:

  • 我觉得您应该花一些时间将这个问题简化为最基本的问题。除此之外,您将永远需要具有 50 个参数的方法。永远。
  • 如果您使用 WHERE ... IN,您应该将数组传递给方法 - 这可能吗?
  • 拥有一个方法 public Cursor findPoiInTable(String inInterval) 并在另一端创建 inInterval 不是更好吗?您可以在 displayListView() 中创建此间隔。
  • 你指的是什么方法? findPoiInTable 是否比您发布的更复杂?在构造 inInterval 字符串时可以有一个变量来保存元素的数量。
  • 不,您的 inInterval 看起来像 ("'" + myVar1 + "'", "'" + myVar2 + "'" ...),您可以将 whereArgs 设为空。跨度>

标签: android database variables methods input


【解决方案1】:

你想要这个--

void myVariableMethod( int... catIds ) {
    for( int catId : catIds ) {
        Log.d( "Output", "catId: " + catId );
    }
}

在方法声明中的类型之后添加省略号将允许您将任意数量的相同类型的参数传递给方法。 catIds 实际上是方法体中的 int[] 数组。

你可以这样调用这个方法:

myVariableMethod( 1, 2, 3, 4 );
myVariableMethod( 1 );
myVariableMethod( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 );
myVariableMethod( 1, 2, 3, 4, 100, 101, 102 );

解决问题的更优雅的方法是使用List&lt;Integer&gt;Set&lt;Integer&gt;,并在评估按钮时添加这些ID。最后,将列表传递给方法并正确评估它。

我的直觉告诉我,您可以改进数据库设计以完全避免 WHERE ... IN 构造,但如果不查看 ERD,这很难确定。

【讨论】:

  • 我实际上无法修改数据库,我必须使用它并且里面已经有超过 8k 条记录。我将尝试这种方式,每次单击按钮时传递我的变量数组并重写我的方法以使其具有该数组作为输入而不是变量本身。但是,我不确定我是否理解您发布的代码:这是否意味着当您使用输入为数组但元素数量并不总是相同的方法时需要此代码?
  • 编辑了答案。您可以根据需要使用尽可能少或尽可能多的参数调用该方法。在该方法中,如果长度正确,您将收到一个数组。
【解决方案2】:

你当然可以使用带 Vararg 的 define you 方法:

 public Cursor findPoiInTable(int ... myVariable) 
{

    //construct String from myVariable array
    StringBuffer sb = new StringBuffer("(");
    for (int i : myVariable)
    {
        sb.append(",?");
    }
    sb.append(")");

    String inInterval = sb.toString();

    String where = COL_CAT1 + " IN " + inInterval + " OR " + COL_CAT2
            + " IN " + inInterval + " OR " + COL_CAT3 + " IN " + inInterval;

    String[] whereArgs = new String[3 * myVariable.length];

 int j = 0
    for (int i = 0; i < 3; i++) 
    {
        whereArgs[6 * i + j] = Integer.toString(myVariable[j++]);
        whereArgs[6 * i + j] = Integer.toString(myVariable[j++]);
        whereArgs[6 * i + j] = Integer.toString(myVariable[j++]);
        whereArgs[6 * i + j] = Integer.toString(myVariable[j++]);
        whereArgs[6 * i + j] = Integer.toString(myVariable[j++]);
        whereArgs[6 * i + j] = Integer.toString(myVariable[j++]);
    }
    Cursor c = myDatabase.query(DATABASE_TABLE, new String[] { KEY_ROWID,
            COL_NAME, COL_STREET}, where, whereArgs, null, null, null);
   return c; 
} 

【讨论】:

    猜你喜欢
    • 2013-05-04
    • 1970-01-01
    • 2023-01-15
    • 2017-07-15
    • 2011-07-08
    • 2012-03-29
    • 1970-01-01
    • 2015-03-05
    • 1970-01-01
    相关资源
    最近更新 更多