[英]Removing certain values from an arraylist
我有一个已导出到ArrayList的csv文件中的数字列表。 现在,问题是我的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)
如果您使用泛型,则您的IDE会抱怨,然后您很容易看到问题所在。 当您尝试将元素从String解析为Double时,编译器实际上将它们视为Object(即使它们实际上是String),但您在此处缺少强制转换。
这是第一个解决方法:
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);
}
您不需要使用.valueOf()
获取值。 您只需要编写Double item = arr.get(i);
获取该索引处的值并继续执行if语句。
Double double = Double.parseDouble(arr.get(i));
您可以将第二个循环滚动到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);
}
尽早转换是一个很好的习惯:)
您的ArrayList没有指定其包含的类型。 因此,将其视为仅包含“对象”。 因此,即使您要向其中添加字符串,当您执行“获取”时,它仍会返回您的对象。 但是Double.valueOf希望字符串解析,而不是对象。 因此,强制转换将起作用:
Double item = Double.valueOf((String) arr.get(i));
但是,您可以使用泛型来指定ArrayList将容纳的项目类型:
List<String> arr=new ArrayList<String>();
现在,您将不需要进行强制转换,因为“ get”将返回字符串。
在阅读时进行过滤时,为什么要创建一个新列表或过滤/修改一个列表:
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);
}
如果您确实要从列表中删除项目,则可以使用迭代器remove方法:
for (Iterator<Double> iterator = arr.iterator(); iterator.hasNext(); ) {
Double next = iterator.next();
if (next < 0.1) {
iterator.remove();
}
}
甚至最好等到Java 8发布(几个小时后),然后使用新的功能性api过滤集合,从而使原始集合保持不变。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.