两层for循环判断,如何优化

[code="java"]

List myRoles = new ArrayList();
List hasRoles = new ArrayList();

public boolean hasRole()
{
for (String my : myRoles)
{
for (String role : hasRoles)
{
if(my.equals(role))
{
return true;
}
}
}

return false;

}
[/code]

上面方面的逻辑是:myRoles集合中的字符串,只要有一个在hasRoles集合中存在,就返回true
但是,这个方法嵌套了2层for循环,效率似乎很低

求改进的方法

用Set做一个myRoles和hasRoles的并集,然后判断这个并集的大小是不是等于myRoles和hasRoles的大小相加,如果不是的话,可定有重复了。

[code="java"]Set totalRoles = new HashSet();
List myRoles = new ArrayList();

List hasRoles = new ArrayList();

public boolean hasRole()

{

// you can use addAll()
for (String my : myRoles)

{

totalRoles.add(my);
}
// you can use addAll()
for (String role : hasRoles)

totalRoles.add(role);

}

return totalRoles.size()==(myRoles.size()+hasRoles.size());
} [/code]

查看下ArrayList.retainAll 和removeAll本质上都做了两个for循环

  1. java8中新特性中有Lambda表达式,类似SQL语句可以简化
  2. 写类似于二分法查找的算法。String.HasCode
  3. 没想到呢!!!

只是需要判断是否重复还有一个方法,使用一个临时map
List myRoles = new ArrayList();
List hasRoles = new ArrayList();

public boolean hasRole(){
    Map<String,String> map = new HashMap();
    //这个尽量选用数据量小的list
    for (String my : myRoles){
        map.put(my, "1");
    }
    int mysize = myRoles.size();
    for (String role : hasRoles){
        map.put(role, "1");
        //重复时mysize == map.size();
        if (map.size() == mysize){
            return true;
        }
    }       
    return false;
}
List<String> myRoles = new ArrayList<String>();   
    myRoles.add("1");
    myRoles.add("2");
    myRoles.add("3");
    myRoles.add("4");

    List<String> hasRoles = new ArrayList<String>();  
    hasRoles.add("2");
    hasRoles.add("3");
    myRoles.removeAll(hasRoles);

    System.out.println(myRoles.size());

结果为:myRoles.size :2
看你的代码好像是要比较2个集合中只要有一个元素同时存在就返回true
你可以试试removeAll方法,如果此方法后他的size有变化,说明有元素共同存在
也能达到你要的效果。你试试效率会不会比双重for要好,只是提供个想法,没试过效率

个人认为这个不需要优化了。即使优化了,带来的性能提升也不大。把优化的关注点放在其他点吧

用Set做一个myRoles和hasRoles的并集,然后判断这个并集的大小是不是等于myRoles和hasRoles的大小相加,如果不是的话,可定有重复了。

[code="java"]Set totalRoles = new HashSet();
List myRoles = new ArrayList();

List hasRoles = new ArrayList();

public boolean hasRole()

{

// you can use addAll()
for (String my : myRoles)

{

totalRoles.add(my);
}
// you can use addAll()
for (String role : hasRoles)

totalRoles.add(role);

}

return totalRoles.size()==(myRoles.size()+hasRoles.size());
} [/code]

查看下ArrayList.retainAll 和removeAll本质上都做了两个for循环

[code="java"]
Map hasRolesMap = new HashMap();
for(String role : hasRoles) {
hasRolesMap.put(role, 1);
}

for(String my : myRoles) {
if(hasRolesMap.get(my) != null) {
return true;
}
}
[/code]

如果你仅仅想要判断两个list中是否含有相同的元素,那么我觉得可以用
你先将两个list合并成一个list,然后将合并后的list放入hashset中
HashSet h = new HashSet(list);
然后输入h.size(),如果他的size和你的两个list的size相同,说明没有重复的,否则有重复的
因为hashset的作用就是去重,他不允许相同的元素存在,只会保留一个

为什么要用双层循环?楼下的想到的办法不敢恭维,首先想到的应该是API的list的contains方法把
for (String my : myRoles){
if(hasRoles.contains(my)){
return true;
}
}
return false;

[code="java"]
List myRoles = new ArrayList();

List hasRoles = new ArrayList();

String hasRolesList = Arrays.deepToString(hasRoles.toArray());

    public boolean hasRole()  
    {  
        for (String my : myRoles)  
        {  
            if (hasRolesList.indexOf(my) > 0)
            {
                 return true;
            }
        }  

        return false;  
    }  

[/code]

说实话,这个最佳答案不敢恭维。
还是第二个答案最靠谱。
你的最佳答案必须循环M+N次
但是第二个答案最坏情况下是M+N,而且没有任何问题,不管List数据是否重复
但是你的最佳答案就不行了。

其实这个不就是求是否有交集吗?

[code="java"]
public boolean hasRole(){
List myRoles = new ArrayList();
List hasRoles = new ArrayList();
hasRoles.retainAll(myRoles);
return hasRoles.size() > 0;
}
这样不用循环就行了
[/code]