Java性能优化-----for循环优化

一杯时光 2015-06-27 10:20:34
要实现一个重组网址的功能,把可能出现的情况给穷举出来,下面代码已经实现(写的比较烂,请见谅),但是在网址比较长的情况下,重组网址的时候遇到大循环问题,导致内存溢出,请各位大侠给优化一下

public static void main(String [] args) {
dealUrl("www。qΒ5。c Om");
}

private static void dealUrl(String url) {
char[] ac = url.toLowerCase().toCharArray();
List<List<String>> charList = new ArrayList<List<String>>();
List<String> tempList = null;
for (int i = 0; i < ac.length; i++) {
tempList = new ArrayList<String>();
int charIntValue = (int) ac[i];
if (Character.isDigit(ac[i])) {//数字
tempList.add(ac[i]+"");
} else if (charIntValue == 46 ||charIntValue == 65294 ){ //点
tempList.add(((char) 46)+"");//半角点
tempList.add(((char) 65294)+"");//全角点
tempList.add("。");//句号
} else if (charIntValue == 79 || charIntValue == 65359
|| charIntValue == 111 || charIntValue == 65327){//字母o
tempList.add(((char) 79)+"");//半角o
tempList.add(((char) 65359)+"");//全角o
tempList.add(((char) 111)+"");//半角大写o
tempList.add(((char) 65327)+"");//全角大写o
tempList.add("0");//零
} else if(charIntValue == 12288 || charIntValue == 32) {//空格
tempList.add(((char) 32)+"");//半角空格
tempList.add(((char) 12288)+"");//全角空格
} else if (charIntValue >= 65281 && charIntValue <= 65374) {//全角
char n = (char) (charIntValue - 65248);
tempList.add(ac[i]+"");//全角字符
tempList.add(n+"");//半角字符
tempList.add((ac[i]+"").toUpperCase());//全角大写
tempList.add((n+"").toUpperCase());//半角大写
} else {
char n = (char) (65248+charIntValue);
tempList.add(ac[i]+"");//半角字符
tempList.add(n+"");//全角字符
tempList.add((ac[i]+"").toUpperCase());//半角大写
tempList.add((n+"").toUpperCase());//全角大写
}
charList.add(tempList);
}
//分组处理
List<List<String>> partChongZuList = new ArrayList<List<String>>();
List<List<String>> partList = null;
int allSize = charList.size();
int fenGe = 4;
int partCount = allSize/fenGe;
if (partCount > 0 ) {
for (int i = 0; i < allSize/fenGe; i++) {
int tempSize = fenGe*(i+1);
if(allSize/tempSize == 1) {
tempSize = allSize;
}
partList = new ArrayList<List<String>>();
for (int k = i*fenGe; k < tempSize; k++) {
partList.add(charList.get(k));
}
partChongZuList .add(chongZu(partList));
}
List<String> aa = chongZu(partChongZuList);
System.out.println(aa.size());
} else {
List<String> aa = chongZu(charList);
System.out.println(aa.size());
}
}

/**
* 重组网址
* @param charList
*/
private static List<String> chongZu(List<List<String>> charList){
List<String> newStr = new ArrayList<String>();
List<String> tempStr = new ArrayList<String>();
int allLn = charList.size();
for (int i = 0; i < allLn; i++) {
List<String> t = charList.get(i);
int tSize = t.size();
for (int j = 0; j < tSize; j++) {
if (i == 0) {
tempStr.add( t.get(j));
} else {
String ns = "";
int nSize = newStr.size();
for (int k = 0 ; k < nSize; k++) {
ns = newStr.get(k);
ns += t.get(j);
tempStr.add(ns);
}
}
}
newStr.clear();
newStr.addAll(tempStr);
tempStr.clear();
System.out.println(newStr.size());
}
return newStr;
}
...全文
690 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
bree06 2015-07-07
  • 打赏
  • 举报
回复
如果只是要笛卡尔集的话,那跟网址应该没什么关系。 如果是网站的话,www.xx.com和WWW.xx.COM一样,所以只需要笛卡尔中间部分即可。
二狗zi 2015-07-07
  • 打赏
  • 举报
回复
重新设计下变量类型吧,很多List<String>型的可以用StringBuffer,List<List<String>>型的可以用List<String>;这个方法chongZu里面嵌套三个循环,内存溢出估计就是这导致的;而且重组网址这么写也太复杂了吧,用正则表达式匹配,得到符号左右两侧的字符串不就行了吗。
一杯时光 2015-07-07
  • 打赏
  • 举报
回复
引用 10 楼 bree06 的回复:
最终的效果是什么呢? 比如www。qΒ5。c Om,最终应该得到什么东西?
比如www。qΒ5。c Om 重组后: www.qb5.com WWW.qb5.COM www.Qb5。CoM ……
  • 打赏
  • 举报
回复
引用 10 楼 bree06 的回复:
最终的效果是什么呢? 比如www。qΒ5。c Om,最终应该得到什么东西?
这是什么网址...你不怕被拉黑么
bree06 2015-07-07
  • 打赏
  • 举报
回复
最终的效果是什么呢? 比如www。qΒ5。c Om,最终应该得到什么东西?
一杯时光 2015-07-07
  • 打赏
  • 举报
回复
引用 3 楼 a291263379 的回复:
代码逻辑写清楚嘛,难道还要人去一句句看你这是什么原理,以后自己说不定也忘了。List里面存List,显然是不太好的 。这种建议用StringBuffer,不要用list。
不好意思,下次注意代码注释和逻辑描述这块;主要逻辑是:先把网址拆分成单个字符,然后把每个字符可能会出现的情况封装成一个集合,再把这些封装好的集合放到一个集合中,最后循环遍历,按照原网站的字符位置进行重组
一杯时光 2015-07-07
  • 打赏
  • 举报
回复
引用 6 楼 attilax 的回复:
很明显你的数据量太大了。。 如果数据量不是很大的情况下,换用小内存占用的变量方式。。 还不行的化,就要加大内存了, 数据量再大,就要用文件io了。。 那个存储放到数据库里面把,起码1千万的数量级轻松实现。。
大内存是可以的,但是不太现实;我尝试用下文件IO方式
一杯时光 2015-07-07
  • 打赏
  • 举报
回复
引用 5 楼 qq_29424637 的回复:
看晕了,也没注释
主要目的就是把网址中可能会出现的字符,重新组合成新的网站,并且每个字符出现的位置和原网站一致

   public static void main(String [] args) {
        dealUrl("www。qΒ5。c Om");
    }
 
    private static void dealUrl(String url) {
    	//把网址转化为小写并拆分成单个字符数组
        char[] ac = url.toLowerCase().toCharArray();
        List<List<String>> charList = new ArrayList<List<String>>();
        //存放网址中每个字符可能出现的情况
        List<String> tempList = null;
        for (int i = 0; i < ac.length; i++) {
            tempList = new ArrayList<String>();
            int charIntValue = (int) ac[i];
            if (Character.isDigit(ac[i])) {//数字
                tempList.add(ac[i]+"");
            } else if (charIntValue == 46 ||charIntValue == 65294 ){ //点
                tempList.add(((char) 46)+"");//半角点
                tempList.add(((char) 65294)+"");//全角点
                tempList.add("。");//句号
            } else if (charIntValue == 79 || charIntValue == 65359 
                    || charIntValue == 111 || charIntValue == 65327){//字母o
                tempList.add(((char) 79)+"");//半角o
                tempList.add(((char) 65359)+"");//全角o
                tempList.add(((char) 111)+"");//半角大写o
                tempList.add(((char) 65327)+"");//全角大写o
                tempList.add("0");//零
            } else if(charIntValue == 12288 || charIntValue == 32) {//空格
                tempList.add(((char) 32)+"");//半角空格
                tempList.add(((char) 12288)+"");//全角空格
            } else if (charIntValue >= 65281 && charIntValue <= 65374) {//全角
                char n = (char) (charIntValue - 65248);
                tempList.add(ac[i]+"");//全角字符
                tempList.add(n+"");//半角字符
                tempList.add((ac[i]+"").toUpperCase());//全角大写
                tempList.add((n+"").toUpperCase());//半角大写
            } else {
                char n = (char) (65248+charIntValue);
                tempList.add(ac[i]+"");//半角字符
                tempList.add(n+"");//全角字符
                tempList.add((ac[i]+"").toUpperCase());//半角大写
                tempList.add((n+"").toUpperCase());//全角大写
            }
            charList.add(tempList);
        }
        //分组处理
        List<List<String>> partChongZuList = new ArrayList<List<String>>();
        List<List<String>> partList = null;
        int allSize = charList.size();
        int fenGe = 4;//按每4个字符一组
        int partCount = allSize/fenGe;
        if (partCount > 0 ) {
            for (int i = 0; i < allSize/fenGe; i++) {
                int tempSize = fenGe*(i+1);
                //如果allSize/tempSize == 1,剩下的字符集合为一组
                if(allSize/tempSize == 1) {
                    tempSize = allSize;
                }
                partList = new ArrayList<List<String>>();
                for (int k = i*fenGe; k < tempSize; k++) {
                    partList.add(charList.get(k));
                }
                //重组部分字符集合,并准备下次重组,eg:www。、 WWW.
                partChongZuList .add(chongZu(partList));
            }
            //重组分组完成后的
            List<String> aa = chongZu(partChongZuList);
            System.out.println(aa.size());
        } else {
            List<String> aa = chongZu(charList);
            System.out.println(aa.size());
        }
    }
 
    /**
     * 重组网址
     * @param charList 
     */
    private static List<String> chongZu(List<List<String>> charList){
        List<String> newStr = new ArrayList<String>();
        List<String> tempStr = new ArrayList<String>();
        int allLn = charList.size();
        for (int i = 0; i < allLn; i++) {
        	//获取字符集合
            List<String> t = charList.get(i);
            int tSize = t.size();
            for (int j = 0; j < tSize; j++) {
            	//外层第一次循环,只需把字符放到tempStr集合中即可
                if (i == 0) {
                    tempStr.add( t.get(j));
                } else {
                    String ns = "";
                    //上次重组后集合的长度
                    int nSize = newStr.size();
                    for (int k = 0 ; k < nSize; k++) {
                        ns = newStr.get(k);
                        //循环累加本次要重组的字符
                        ns += t.get(j);
                        //存放重组后的字符串
                        tempStr.add(ns);
                    }
                }
            }
            newStr.clear();
            newStr.addAll(tempStr);
            tempStr.clear();
            System.out.println(newStr.size());
        }
        return newStr;
    }
一杯时光 2015-07-07
  • 打赏
  • 举报
回复
引用 14 楼 bree06 的回复:
如果只是要笛卡尔集的话,那跟网址应该没什么关系。 如果是网站的话,www.xx.com和WWW.xx.COM一样,所以只需要笛卡尔中间部分即可。
学习了,我查询了笛卡尔集的概念,要的就是笛卡尔集;小弟读书少,不知道笛卡尔集
attilax 2015-07-01
  • 打赏
  • 举报
回复
很明显你的数据量太大了。。 如果数据量不是很大的情况下,换用小内存占用的变量方式。。 还不行的化,就要加大内存了, 数据量再大,就要用文件io了。。 那个存储放到数据库里面把,起码1千万的数量级轻松实现。。
qq_29424637 2015-06-30
  • 打赏
  • 举报
回复
看晕了,也没注释
火柴棍的坚强 2015-06-30
  • 打赏
  • 举报
回复
豫让_______ 2015-06-30
  • 打赏
  • 举报
回复
代码逻辑写清楚嘛,难道还要人去一句句看你这是什么原理,以后自己说不定也忘了。List里面存List,显然是不太好的 。这种建议用StringBuffer,不要用list。
移动大金条 2015-06-29
  • 打赏
  • 举报
回复
List<string> t = charList
戴子 2015-06-29
  • 打赏
  • 举报
回复
我去,尼玛,我一运行你这代码,ECLIPSE直接蹦了

67,515

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧