0

我有一个方法,它以对象的形式接受可变数量和类型的参数。我想仅计算这些参数中数字的中位数。我使用列表插入元素(数字),然后使用集合对列表进行排序。每当我将整数和双精度数作为参数传递时,我都会在 Collections.sort() 行中收到 Classcast 异常。这是我的方法:

public Object median(Object... O) {

    List l = new ArrayList<Object>();
    for (int i = 0; i < O.length; i++) {
        if (Number.class.isAssignableFrom(O[i].getClass())) {
            l.add(O[i]);
        } else {
            try {
                double d = Double.parseDouble(O[i].toString());
                l.add(d);
            } catch (Exception e) {

            }
        }
    }
    Collections.sort(l);
    double sum = 0;
    if (l.size() % 2 == 0) {

        if (l.get((l.size()) / 2 - 1) instanceof Double) {
            Double d = (Double) l.get((l.size()) / 2 - 1);
            sum += d;
        } else if (l.get((l.size()) / 2 - 1) instanceof Integer) {
            Integer d = (Integer) l.get((l.size()) / 2 - 1);
            sum += d;
        }
        if (l.get((l.size()) / 2) instanceof Double) {
            Double d1 = (Double) l.get(l.size() / 2);
            sum += d1;
        } else if (l.get((l.size()) / 2) instanceof Integer) {
            Integer d1 = (Integer) l.get(l.size() / 2);
            sum += d1;
        }

        return sum / 2;
    } else {
        if (l.get((l.size()) / 2) instanceof Double) {
            Double d1 = (Double) l.get(l.size() / 2);
            sum = d1;
        } else if (l.get((l.size()) / 2) instanceof Integer) {
            Integer d1 = (Integer) l.get(l.size() / 2);
            sum = d1;
        }
        return sum;
       }

    }

我可以以任何方式调用该方法,例如:

  1. System.out.println("中位数------"+cmp.median(13, 18, 13, 14, 13, 16, 14, 21, 13));

  2. System.out.println("中位数---------"+cmp.median(13, 18.1, 13, 14, 13, 16, 14, 21, 13));

  3. System.out.println("中位数---------"+cmp.median(13, 18, 13,"13", 14, 13, 16, 14, 21,13);

  4. System.out.println("中位数---------"+cmp.median(13, 18,"xyz", 13, 14, 13, 16, 14,21,13));

我认为 Collections.sort() 不能与 Doubles 一起使用。请提出出路!

4

4 回答 4

1

兑换

List l = new ArrayList<Object>();

List<Number> l = new ArrayList<Number>();

并使用: 在for循环内,有:

if(O[i] instanceof Number)
   l.add((Number)O[i]);

并对它们进行排序:

Collections.sort(l, new Comparator<Number>(){
 @Override
  public void compare(Number t1, Number t2){
   if(t1.doubleValue<t2.doubleValue)
    return -1;
    else if(t1.doubleValue==t2.doubleValue)
       return 0 
    else return 1
}
}

它正确抛出ClassCastException,因为l定义的是 type 的列表Object。根据声明Object不执行Comparable。因此,您需要提供一个比较器来完成这项工作

于 2013-04-15T11:46:43.900 回答
0

Method to find median of any number and type of arguments

@Override
public Object median(Object... O) {
    List<Double> l = new ArrayList<Double>();
    for (int i = 0; i < O.length; i++) {
        if (Number.class.isAssignableFrom(O[i].getClass())) {
            if (O[i] instanceof Double) {
                Double d = (Double) O[i];
                l.add(d);

            } else if (O[i] instanceof Integer) {
                Integer j = (Integer) O[i];
                double d = Double.parseDouble(Integer.toString(j));
                l.add(d);
            }
        } else {
            try {
                double d = Double.parseDouble(O[i].toString());
                l.add(d);
            } catch (Exception e) {

            }
        }
    }
    Double[] array = new Double[(l.size())];
    l.toArray(array);
    Arrays.sort(array);
    double sum = 0;
    if (array.length % 2 == 0) {

        sum = array[array.length / 2 - 1] + array[array.length / 2];

        return sum / 2;
    } else {

        return array[array.length / 2];
    }

}
于 2013-04-16T08:31:50.587 回答
0

我想问题出在你的 else 块上。

如果您的控制流转到 else 则意味着该对象不是数字(双精度或其他方式),因此将其添加到列表中根本不明智。

同样在您的 If 块中,您可能应该区分各种数字,即 Integer、Double 等,并相应地进行转换。

于 2013-04-15T11:54:15.293 回答
0

我会做类似的事情:

public Object median(Object... objs) {
  List<Number> nrs = extractNumbers(objs);
  // do whatever with the numbers
}

private List<Number> extractNumbers(Object[] objs) {
   final List<Number> nrs = new ArrayList<Number>();
   for(final Object o:objs){
      if(isNumber(o)){
        nrs.add(getNumber(o));
      }
   }
   return nrs;
}
private boolean isNumber(Object o){
  Number.class.isAssignableFrom(o.getClass());
}
private Number getNumber(Object o){
  return (Number) o;
}

然后您可以修改isNumber/getNumber方法以适应您的识别/解析需求,而不会影响算法的其余部分

于 2013-04-15T11:55:00.180 回答