两层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循环,效率似乎很低

求改进的方法

liujiaoshui
liujiaoshui List a = new ArrayList(); List b= new ArrayList(); Set set = new HashSet(); set.addAll(a ); return set.addAll(b);
大约 6 年之前 回复

12个回答

用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循环

luhaixun
luhaixun 那你可以先把list做成set 就可以避免了
大约 6 年之前 回复
bylijinnan
bylijinnan 如果 myRoles 或者 hasRoles 本身就有重复的元素时,这个算法就不对了
大约 6 年之前 回复
  1. java8中新特性中有Lambda表达式,类似SQL语句可以简化
  2. 写类似于二分法查找的算法。String.HasCode
  3. 没想到呢!!!
guiqian0725
guiqian0725 我就是举个例子 ,不一定非要二分查找
大约 6 年之前 回复
java_web_hack1
孤好梦中杀人 二分查找先要排序吧,排序也要消耗效率吧
大约 6 年之前 回复

只是需要判断是否重复还有一个方法,使用一个临时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;
}
iteye_6932
iteye_6932 应该是int mysize = map.size(); 然后if(map.size() == mysize++)吧。 myRoles和hasRoles并不一定是排好序的吧?而且也可能有重复的吧?
大约 6 年之前 回复
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;

Iloveyou111111111111
Iloveyou111111111111 这真是舍近求远 有api不用
大约 6 年之前 回复
msdghs
哈尼 不错 认同
大约 6 年之前 回复

[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]

hukuas
hukuas 这样应该比两层for循环的效率底,字符串匹配算法应该使用的是KMP算法,时间复杂度是O(m+n),m,n是子串和父串的长度
大约 6 年之前 回复
forhd
handong890 hasRolesList.indexOf(my) >= 0
大约 6 年之前 回复
共12条数据 1 尾页
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问