我有一个csv文件中的数字列表,我已导出到ArrayList。现在,问题是我的ArrayList是String而不是double。我尝试过使用
ArrayList<Double> arr = new ArrayList<Double>();`
但它给了我一个错误。
我想删除ArrayList中小于0.1的任何数字。这是我的代码:
public class Example1
{
public static void main(String[] args) throws InvalidFormatException, IOException{
ArrayList arr=new ArrayList();
File f=new File("C:\\java\\marchcalllast.csv");
Scanner in=new Scanner(f).useDelimiter(",");
while(in.hasNext())
{
arr.add(in.next());
}
for (int i = 0; i < arr.size(); i++){
Double item = Double.valueOf(arr.get(i));
if (item < 0.1) {
arr.remove(i);
}
}
System.out.println(arr);
它给了我以下错误:
错误:找不到valueOf(java.lang.Object)的合适方法 方法java.lang.Double.valueOf(double)不适用 (实际参数java.lang.Object不能通过方法调用转换转换为double) 方法java.lang.Double.valueOf(java.lang.String)不适用 (实际参数java.lang.Object不能通过方法调用转换转换为java.lang.String)
答案 0 :(得分:1)
如果您使用泛型,您的IDE会抱怨,您可以很容易地看到问题。当你尝试将元素从String解析为Double时,它们实际上被编译器视为Object(即使它们实际上是字符串),你在这里错过了一个演员。
这是第一个修复:
public static void main(String[] args) throws IOException {
List<Double> arr = new ArrayList<Double>();
File f = new File("C:\\java\\marchcalllast.csv");
Scanner in = new Scanner(f).useDelimiter(",");
while (in.hasNext()) {
arr.add(Double.valueOf(in.next()));
}
for (Double item : arr) {
if (item < 0.1) {
arr.remove(item); // This is not allowed here, you are iterating on arr
}
}
System.out.println(arr);
}
现在,还有另一个错误:在迭代时无法从集合中删除元素。要解决此问题,您可以使用第二个临时集合:
public static void main(String[] args) throws IOException {
List<Double> arr = new ArrayList<Double>();
File f = new File("C:\\java\\marchcalllast.csv");
Scanner in = new Scanner(f).useDelimiter(",");
while (in.hasNext()) {
arr.add(Double.valueOf(in.next()));
}
List<Double> toRemove = new ArrayList<Double>();
for (Double item : arr) {
if (item < 0.1) {
toRemove.add(item);
}
}
arr.removeAll(toRemove);
System.out.println(arr);
}
答案 1 :(得分:0)
您无需使用.valueOf()
获取值。您只需要编写Double item = arr.get(i);
来获取此索引处的值并继续使用if语句。
答案 2 :(得分:0)
Double double = Double.parseDouble(arr.get(i));
答案 3 :(得分:0)
您可以将第二个循环滚动到CSV解析阶段。如果您知道输入应该是数字,则可以使用异常处理忽略非数字输入。
以下是一个例子:
public static void main(String[] args) throws InvalidFormatException, IOException{
List arr=new ArrayList();
File f=new File("C:\\java\\marchcalllast.csv");
Scanner in=new Scanner(f).useDelimiter(",");
while(in.hasNext()){
String nextToken = in.next();
try{
Double tokenAsNumber = Double.parseDouble(nextToken);
if(tokenAsNumber >= 0.1){
arr.add(tokenAsNumber);
}
else{
System.out.println("Ignoring value less than 0.1: "+tokenAsNumber);
}
}
catch(NumberFormatException nfe){
System.err.println(nextToken + " is not a number, ignoring");
}
}
System.out.println(arr);
}
早期转换是非常好的做法:)
答案 4 :(得分:0)
您的ArrayList未指定其包含的类型。所以它被视为只包含“对象”。所以,即使你正在添加字符串,当你做“获取”时,它仍然会返回对象。但Double.valueOf希望字符串解析,而不是对象。 所以演员会工作:
Double item = Double.valueOf((String) arr.get(i));
但是,您可以使用泛型来指定ArrayList将包含的项目类型:
List<String> arr=new ArrayList<String>();
现在,你不需要那个演员阵容,因为“get”会让你回到弦乐。
答案 5 :(得分:0)
为什么在读取时过滤时创建新列表或过滤/修改新列表:
public class FilterDouble {
public static void main(String[] args) throws IOException {
File file = new File("C:\\java\\marchcalllast.csv");
Scanner in = new Scanner(file).useDelimiter(",");
List<Double> list = new ArrayList<>();
while (in.hasNext()) {
final double value = Double.parseDouble(in.next());
if (value >= 0.1) {
list.add(value);
}
}
System.out.println(list);
}
如果你真的想从List中删除项目,我会使用iterator remove方法:
for (Iterator<Double> iterator = arr.iterator(); iterator.hasNext(); ) {
Double next = iterator.next();
if (next < 0.1) {
iterator.remove();
}
}
或者甚至更好地等到Java 8发布(几个小时后)并使用新的功能api来过滤原始集合不受影响的集合。