我有一个方法,它以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;
}
}
我可以用以下任何方式调用该方法:
System.out.println(“Median ---------”+ cmp.median(13,18,13,14,13,16,14,21,13)); < / p>
System.out.println(“Median ---------”+ cmp.median(13,18.1,13,14,13,16,14,21,13)); < / p>
System.out.println(“Median ---------”+ cmp.median(13,18,13,“13”,14,13,16,14,21,13) );
System.out.println(“Median ---------”+ cmp.median(13,18,“xyz”,13,14,13,16,14,21,13) ));
我认为Collections.sort()无法使用双打。请建议出路!
答案 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];
}
}