当我将 ArrayList 的 get 方法传递给一个变量时,它使用的是整个 ArrayList
Posted
技术标签:
【中文标题】当我将 ArrayList 的 get 方法传递给一个变量时,它使用的是整个 ArrayList【英文标题】:When I pass an ArrayList's get method a variable, it's using the whole ArrayList 【发布时间】:2016-02-10 11:04:19 【问题描述】:由于某种原因,当我传递我的 ArrayList(它是来自 Java 的 Lang.* 的基本 ArrayList)一个 int 变量时,而不是在变量 int 的索引处获取项目(例如: i = 0; arrayList.get(i);
应该是第一个ArrayList 中的项目) - 它调用 WHOLE 列表。
下面是有问题的方法:
public ZipCode findZip (int zip)
ZipCode aZip = new ZipCode(00000);
//System.out.println(zips.get(0)); here gives 99501,ANCHORAGE,AK
//System.out.println(zips.get(0).getZipCode()); here gives 99501
for(int i = 0; i < zips.size(); i++)
if(zips.get(i).getZipCode() == zip)
aZip = zips.get(i);
//System.out.print(aZip); here gives the zip codes from the whole array
else
aZip = null;
return aZip;
//Therefore, aZip is ALWAYS null. Even if it exists.
我尝试了一系列故障排除来解决这个问题。到目前为止,我了解到当我输入一个直整数时不会出现问题(例如: arrayList.get(1);
正常获取第二项)。不幸的是,没有要显示的编译器错误。
null
。
我需要使用一个 int 所以我可以增加它来遍历列表,这也很不幸。
更大的程序片段:(与我之前的问题相同)
import java.util.*;
import java.io.*;
import java.lang.Math;
public class ZipCodeDatabase
//Field
private ArrayList<ZipCode> zips;
//Constructor
public ZipCodeDatabase ()
zips = new ArrayList<ZipCode> ();
//Mutator Method
public void readZipCodeData(String filename)
Scanner inFS = null;
FileInputStream fileByteStream = null;
try
// open the File and set delimiters
fileByteStream = new FileInputStream(filename);
inFS = new Scanner(fileByteStream);
inFS.useDelimiter("[,\r\n]+");
// continue while there is more data to read
while(inFS.hasNext())
//read in all input
int aZip = inFS.nextInt();
String aCity = inFS.next();
String aState = inFS.next();
double aLat = inFS.nextDouble();
double aLon = inFS.nextDouble();
//Create and add new zipcode
ZipCode newZip = new ZipCode(aZip, aCity, aState, aLat, aLon);
zips.add(newZip);
fileByteStream.close();
// Could not find file
catch(FileNotFoundException error1)
System.out.println("Failed to read the data file: " + filename);
// error while reading the file
catch(IOException error2)
System.out.println("Oops! Error related to: " + filename);
//Accessor Methods
public ZipCode findZip (int zip)
ZipCode aZip = new ZipCode(00000);
for(int i = 0; i < zips.size(); i++)
if(zips.get(i).getZipCode() == zip)
aZip = zips.get(i);
else
aZip = null;
return aZip;
这是 getZipCode() 方法(它返回邮政编码 int,是包含纬度和经度的一小部分 int 的一部分;我有一个数组):
public int getZipCode ()
return zipCode;
【问题讨论】:
什么是zips
?您能否展示一个重现问题的完整示例?
你为什么有else aZip = null
?这将更改aZip
以引用null
,即使在循环的早期找到匹配项也是如此。我认为您根本不想要 else
声明。
向我们展示来自zips
和 ZipCode 类的代码。
getZipCode()
的返回类型是什么?
你在哪里发布了getZipCode()
方法?
【参考方案1】:
当您找到邮政编码时,您不会停止循环,因此您在循环中的下一次迭代通常会将您的返回值设置为 null。将您的声明更改为:
为您的教授编辑:
ZipCode aZip = null;
for(int i = 0; i < zips.size() && aZip == null; i++)
if(zips.get(i).getZipCode() == zip)
aZip = zips.get(i);
if (aZip == null)
aZip = new ZipCode(00000);
// return new ZipCode(00000); would be better
return aZip;
【讨论】:
我必须返回一个变量,教授对循环内的返回很生气。 然后在aZip = zips.get(i);
之后使用break
关键字。 break
表示不再循环,因为我已经得到了我想要的东西。
Is it bad style to use 'return' to break a for loop in Java?
您也可以将 break 隐式放入 for
语句声明中:for(int i = 0; i < zips.size() && aZip.getZipCode() == 0; i++)
。但在我的书中,从循环内部返回很好。
但是。这给了我一个想法。【参考方案2】:
由于您在找到匹配项后没有停止循环,因此下一次迭代的结果将覆盖您的匹配项,这很可能是一个不匹配项,因此用null
覆盖它。有几种选择:
break
出:
public ZipCode findZip (int zip)
ZipCode aZip = null;
for(int i = 0; i < zips.size(); i++)
if(zips.get(i).getZipCode() == zip)
aZip = zips.get(i);
break;
else
aZip = null;
return aZip;
改变循环条件:
public ZipCode findZip (int zip)
ZipCode aZip = null;
for(int i = 0; i < zips.size() && aZip==null; i++)
if(zips.get(i).getZipCode() == zip)
aZip = zips.get(i);
else
aZip = null;
return aZip;
不要覆盖:
public ZipCode findZip (int zip)
ZipCode aZip = null;
for(int i = 0; i < zips.size(); i++)
if(zips.get(i).getZipCode() == zip)
aZip = zips.get(i);
else
continue; // obsolete, but you said, your prof insist on it…
return aZip;
最后一点,最干净的解决方案是在 ZipCode
类中提供正确的 equals
方法。如果ZipCode
类有正确的equals
实现,您可以简单地实现该方法:
public ZipCode findZip (int zip)
ZipCode aZip = new ZipCode(zip);
if(zips.contains(aZip))
return aZip;
else
return null;
或者,甚至更短:
public ZipCode findZip (int zip)
ZipCode aZip = new ZipCode(zip);
return zips.contains(aZip)? aZip: null;
【讨论】:
【参考方案3】:谢谢大家!
虽然其他答案确实有效,但这是一个不同的解决方案,它给出了似乎正确的答案:public ZipCode findZip (int zip)
ZipCode aZip = null;
for(int i = 0; i < zips.size(); i++)
if(zips.get(i).getZipCode() == zip)
aZip = zips.get(i);
return aZip;
【讨论】:
这就是我的答案! :P Mine 已经过优化,因为它会在找到该项目时停止迭代。 当然可以。是 你 说 else 部分是你的教授要求的。 null 是,所以我不知道另一种说法【参考方案4】:问题在于,当您找到目标 ZipCode
时,您并没有停止迭代,而是在后续迭代中将 null
分配给您的 aZip
变量。
要解决它,您可以使用条件来停止迭代:
ZipCode aZip = null;
for (int i = 0; (i < zips.size()) && (aZip == null); i++)
if (zips.get(i).getZipCode() == zip)
aZip = zips.get(i); // When you set this, aZip will no longer be == null
【讨论】:
以上是关于当我将 ArrayList 的 get 方法传递给一个变量时,它使用的是整个 ArrayList的主要内容,如果未能解决你的问题,请参考以下文章