有多种方法可以解决这个问题。
- 使用 while 循环
- 使用带有附加停止条件的 for 循环
- 使用break关键字。
在介绍我们的逻辑之前先创建一个模板:
public long findLocationId(String locationName) throws SystemException
{
if(locationName == null) { //Here we cover first issue.
throw new IllegalArgumentException("THe locationName must not be null");
}
long locId = Long.MIN_VALUE; //We declare a default value that will be returned if none match found.
Collection<Location> locationList = getLocationList(); //The location can be read from another method so we are not binded to field.
if(locationList == null || locationList.isEmpty()) {
return locId; // Or throw an exception about invalid state.
}
//Place for the logic
return locId;
}
通常,当我们不知道何时要停止迭代时,这表明我们应该从 while 循环开始。
所以让我们试试吧。
解决方案 1 - while 方式。
Iterator<Location> iterator = locationList.iterator();
while(iterator.hasNext() && Long.MIN_VALUE != locId) {
Location location = iterator.next();
if(locationName.equalsIgnoreCase(location.getLocationName())) {
locId = location.getLocationId(); // This will change the locId, so second condition will be no longer true and loop will end.
}
}
优点: - 它有效
缺点: - 离开迭代器
我们不应该留下迭代器,因为这很容易出错。这导致我们下一个解决方案。
解决方案 2 - 我们使用迭代器的模式而不是 while。
for(Iterator<Location> iterator2 = locationList.iterator();iterator.hasNext() && Long.MIN_VALUE != locId;) {
Location location = iterator.next();
if(locationName.equalsIgnoreCase(location.getLocationName())) {
locId = location.getLocationId(); // This will change the locId, so second condition will be no longer true and loop will end.
}
}
优点 - 它有效
缺点 - 它很复杂,我们必须在阅读此代码时停止。
由于上述解决方案不易阅读,因此也应删除。
解决方案 3 - 为什么 break 有用。
for(Location location : locationList) {
if(locationName.equalsIgnoreCase(location.getLocationName())) {
locId = location.getLocationId();
break;
}
}
优点 - 有效 - 可读
缺点 - 无
结论是代码应该是可读的。使用break
,我们指出我们找到了匹配并且我们不想再继续前进。
美好的。但是案件什么时候location
被发现呢?
我们返回的 OP 示例1L
。这不是最佳选择,因为该值很可能用作 ID。
在前面的示例中,我使用了 long 的最小值。这在某些情况下是可以接受的,但我们仍然需要验证方法结果,并记录它。
最终的解决方案是额外的循环出口,即return
关键字。
public long findLocationId(String locationName) throws SystemException
{
if(locationName == null) { //Here we cover fist issue.
throw new IllegalArgumentException("THe locationName must not be null");
}
Collection<Location> locationList = getLocationList(); //The location can be read from another method so we are not binded to field.
if(locationList == null) {
throw new IllegalStateException("THe location list was not initialized");
}
for(Location location : locationList) {
if(locationName.equalsIgnoreCase(location.getLocationName())) {
return location.getLocationId(); //We exit from the method.
}
}
throw new SystemException("Could not found location for name:" + locationName);
}
附加说明
在示例 OP havelocation == findLoc.getLocationName()
中,此代码的问题是我们不应该使用==
来比较对象类型(详细信息)。当我们处理 String 类时推荐的方法是使用方法String#equals(Object)
或 'String#equalsIgnoreCase(String)'。对于这个例子,我使用了第二个选项。