简体   繁体   English

使用集合引用作为if语句条件而不进行比较?

[英]Using a collection reference as an if statement condition without a comparison?

I'm a little embarrassed to be asking this because I'm sure this is a very basic question but having searched and thought about it I still can't work this out. 我有点不好意思问这个,因为我确定这是一个非常基本的问题,但经过搜索和思考,我仍然无法解决这个问题。

The code is from a class the tutor walked through developing during a tutorial on collections for my course. 代码来自一个班级,导师在我的课程收集教程中进行了开发。 The class represents a crime sheet of districts with associated crime codes. 该类代表具有相关犯罪代码的地区犯罪表。 The sheet is implemented as a SortedMap where the keys are of type String (representing the district) and the values are an ArrayList of Integers (representing the crime codes). 工作表实现为SortedMap,其中键的类型为String(表示区),值为Integers的ArrayList(表示犯罪代码)。

There is one method that we didn't manage to finish during the tutorial that the tutor sent on a copy of and I can't follow the logic. 有一种方法,我们在教程中没有设法完成导师发送的副本,我无法遵循逻辑。 The code for the method is below 该方法的代码如下

/**
 * displays districts affected by given crime code
 * 
 *     @param Integer crime code
 *     @return     none
 */
public void displayAffectedDistricts(Integer crimeCode)
{
    ArrayList<Integer> searchCode;
    for(String eachDistrict:  crimeTable.keySet())
    {
        searchCode = new ArrayList<Integer>();
        searchCode.add(crimeCode);
        if(!(searchCode.retainAll(crimeTable.get(eachDistrict))))
        {
           System.out.println("Code "+crimeCode+" found in district "+eachDistrict);
         } 
    }
}

I've run the code and can see that this works but I can't follow the logic of the if condition. 我运行代码,可以看到这有效,但我无法遵循if条件的逻辑。

My understanding is that searchCode.retainAll(crimeTable.get(eachDistrict)) will evaluate to the reference to the list searchCode and that, at that point, searchCode will contain the single value given by the crimeCode argument if the Map entry for eachDistrict has crimeCode in it's set of values or will otherwise be empty. 我的理解是searchCode.retainAll(crimeTable.get(eachDistrict))将评估对列表searchCode的引用,并且,此时,如果eachDistrict的Map条目具有crimeCode,则searchCode将包含crimeCode参数给出的单个值在它的一组值或否则将为空。

As far as I'm aware that's not a boolean value so can't be used as an if condition without a comparison operator. 据我所知,这不是布尔值,因此不能用作没有比较运算符的if条件。

Could someone please explain what I'm missing? 有人可以解释一下我缺少的东西吗?

It's pretty bad code. 这是非常糟糕的代码。 But, here's how it works: 但是,这是它的工作原理:

The retainAll() method returns true if the list changed because of the operation. 如果列表因操作而更改, retainAll()方法将返回true A list is created that contains the target code, and if the other list contains it, the list will not change. 将创建一个包含目标代码的列表,如果另一个列表包含目标代码,则列表不会更改。

I would severely mark down the person who wrote this if I was marking it, because it's obtuse. 如果我标记它,我会严厉标记写这个的人,因为它是钝的。 Here's a better implementation, uses much less code, is straightforward and easy to understand and performs better too: 这是一个更好的实现,使用更少的代码,简单易懂,性能也更好:

public void displayAffectedDistricts(Integer crimeCode) {
    for (String eachDistrict : crimeTable.keySet()) {
        if (crimeTable.get(eachDistrict).contains(crimeCode)) {
           System.out.println("Code "+crimeCode+" found in district "+eachDistrict);
        } 
    }
}

But even this can be improved upon, by using even less code and performs much better: 但即便如此,通过使用更少的代码执行得更好可以改进:

public void displayAffectedDistricts(Integer crimeCode) {
    for (Map.Entry<String, ArrayList<Integer>> entry : crimeTable.entrySet()) {
        if (entry.getValue().contains(crimeCode)) {
           System.out.println("Code "+crimeCode+" found in district "+entry.getKey());
        } 
    }
}

This last version avoids all the numerous calls to get() . 最后一个版本避免了对get()所有大量调用。 It is the most elite way of coding it. 它是编码它的最精英方式。 Suggest this to your teacher, who by the way should find another job. 建议你的老师顺便找一份工作。

The javadoc of retainAll() says: retainAll()的javadoc说:

Returns:
true if this list changed as a result of the call

The method could also be designed to return the resulting list. 该方法还可以设计为返回结果列表。 However, this would obscure that the change was not performed on a copy, but the original list. 但是,这会掩盖未在副本上执行更改,而是在原始列表中执行更改。 Moreover, it is pretty handy to know if the set operation has caused a change. 此外,了解设置操作是否已导致更改非常方便。

retainAll returns true if this list changed as a result of the call. 如果此列表因调用而更改,则retainAll返回true

So 所以

!(searchCode.retainAll(crimeTable.get(eachDistrict)))

is equals to 等于

crimeTable.get(eachDistrict).contains(crimeCode)

retainAll is defined in java.util.List and return a boolean as return value. retainAll在java.util.List中定义,并返回一个boolean作为返回值。 So this value can be used as the condition of the if statement. 所以这个值可以用作if语句的条件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM