查找变量类型参数的中位数

时间:2013-04-15 11:44:00

标签: java classcastexception

我有一个方法,它以Object的形式接受可变数量和类型的参数。我想计算那些参数中只有数字的中位数。我使用Lists插入元素(数字),然后使用Collections对List进行排序。每当我传递整数和双精度作为参数时,我在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(“Median ---------”+ cmp.median(13,18,13,14,13,16,14,21,13)); < / p>

  2. System.out.println(“Median ---------”+ cmp.median(13,18.1,13,14,13,16,14,21,13)); < / p>

  3. System.out.println(“Median ---------”+ cmp.median(13,18,13,“13”,14,13,16,14,21,13) );

  4. System.out.println(“Median ---------”+ cmp.median(13,18,“xyz”,13,14,13,16,14,21,13) ));

  5. 我认为Collections.sort()无法使用双打。请建议出路!

4 个答案:

答案 0 :(得分: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定义的是Object类型的列表。根据声明Object未实现Comparable。因此,您需要提供一个完成工作的比较器

答案 1 :(得分:0)

我猜问题是你的其他阻止。

如果您的控制流程转到else,则表示该对象不是数字(双重或其他方式),因此将其添加到列表中是不明智的。

同样在你的If块中你应该区分各种数字,例如Integer,Double等,并相应地进行投射。

答案 2 :(得分: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方法以满足您的识别/解析需求,而不会影响算法的其余部分

答案 3 :(得分:0)

查找任意数量和参数类型的中位数的方法

@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];
    }

}