电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

高效的找出两个List中的不同元素


发布日期:2021/9/7
 
如题有List<String> list和List<String> list两个集合各有上万个元素怎样取出两个集合中不同的元素?

方法:遍历两个集合

package comczptest;import javautilArrayList;import javautilList;public class TestList {

public static void main(String[] args) {

List<String> list = new ArrayList<String>()

List<String> list = new ArrayList<String>()

for (int i = ; i < ; i++) {

listadd(test+i)

listadd(test+i*

}

getDiffrent(listlist

//输出total times

}

/**

* 获取连个List的不同元素

* @param list

* @return

*/

private static List<String> getDiffrent(List<String> list List<String> list) {

long st = SystemnanoTime()

List<String> diff = new ArrayList<String>()

for(String str:list

{

if(!ntains(str))

{

diffadd(str)

}

}

Systemoutprintln(total times +(SystemnanoTime()st))

return diff;

}}

千万不要采用这种方法总共要循环的次数是两个List的size相乘的积从输出看耗时也是比较长的那么我们有没有其他的方法呢?当然有

方法:采用List提供的retainAll()方法

package comczptest;import javautilArrayList;import javautilList;public class TestList {

public static void main(String[] args) {

List<String> list = new ArrayList<String>()

List<String> list = new ArrayList<String>()

for (int i = ; i < ; i++) {

listadd(test+i)

listadd(test+i*

}

getDiffrent(listlist

//输出total times

getDiffrent(listlist

//输出getDiffrent total times

}

/**

* 获取连个List的不同元素

* @param list

* @param list

* @return

*/

private static List<String> getDiffrent(List<String> list List<String> list) {

long st = SystemnanoTime()

listretainAll(list

Systemoutprintln(getDiffrent total times +(SystemnanoTime()st))

return list;

}

/**

* 获取连个List的不同元素

* @param list

* @param list

* @return

*/

private static List<String> getDiffrent(List<String> list List<String> list) {

long st = SystemnanoTime()

List<String> diff = new ArrayList<String>()

for(String str:list

{

if(!ntains(str))

{

diffadd(str)

}

}

Systemoutprintln(getDiffrent total times +(SystemnanoTime()st))

return diff;

}}

很遗憾这种方式虽然只要几行代码就搞定但是这个却更耗时查看retainAll()的源码

public boolean retainAll(Collection<?> c) {

boolean modified = false;

Iterator<E> e = iterator()

while (ehasNext()) {

if (!ntains(enext())) {

eremove()

modified = true;

}

}

return modified;

}

无需解释这个耗时是必然的那么我们还有没有更好的办法呢?仔细分析以上两个方法中我都做了mXn次循环其实完全没有必要循环这么多次我们的需求是找出两个List中的不同元素那么我可以这样考虑用一个map存放lsit的所有元素其中的key为lsit的各个元素value为该元素出现的次数接着把list的所有元素也放到map里如果已经存在则value加最后我们只要取出map里value为的元素即可这样我们只需循环m+n次大大减少了循环的次数

package comczptest;import javautilArrayList;import javautilHashMap;import javautilList;import javautilMap;public class TestList {

public static void main(String[] args) {

List<String> list = new ArrayList<String>()

List<String> list = new ArrayList<String>()

for (int i = ; i < ; i++) {

listadd(test+i)

listadd(test+i*

}

getDiffrent(listlist

//输出total times

getDiffrent(listlist

//输出getDiffrent total times

getDiffrent(listlist

//输出getDiffrent total times

}

/**

* 获取连个List的不同元素

* @param list

* @param list

* @return

*/

private static List<String> getDiffrent(List<String> list List<String> list) {

long st = SystemnanoTime()

Map<StringInteger> map = new HashMap<StringInteger>(listsize()+listsize())

List<String> diff = new ArrayList<String>()

for (String string : list) {

mapput(string

}

for (String string : list) {

Integer cc = mapget(string)

if(cc!=null)

{

mapput(string ++cc)

continue;

}

mapput(string

}

for(MapEntry<String Integer> entry:mapentrySet())

{

if(entrygetValue()==

{

diffadd(entrygetKey())

}

}

Systemoutprintln(getDiffrent total times +(SystemnanoTime()st))

return list;

}

/**

* 获取连个List的不同元素

* @param list

* @param list

* @return

*/

private static List<String> getDiffrent(List<String> list List<String> list) {

long st = SystemnanoTime()

listretainAll(list

Systemoutprintln(getDiffrent total times +(SystemnanoTime()st))

return list;

}

/**

* 获取连个List的不同元素

* @param list

* @param list

* @return

*/

private static List<String> getDiffrent(List<String> list List<String> list) {

long st = SystemnanoTime()

List<String> diff = new ArrayList<String>()

for(String str:list

{

if(!ntains(str))

{

diffadd(str)

}

}

Systemoutprintln(getDiffrent total times +(SystemnanoTime()st))

return diff;

}}

显然这种方法大大减少耗时是方法/是方法/这个性能的提升时相当可观的但是这不是最佳的解决方法观察方法我们只是随机取了一个list作为首次添加的标准这样一旦我们的list比list的size大则我们第二次put时的if判断也会耗时做如下改进

package comczptest;import javautilArrayList;import javautilHashMap;import javautilList;import javautilMap;public class TestList {

public static void main(String[] args) {

List<String> list = new ArrayList<String>()

List<String> list = new ArrayList<String>()

for (int i = ; i < ; i++) {

listadd(test+i)

listadd(test+i*

}

getDiffrent(listlist

getDiffrent(listlist

getDiffrent(listlist

getDiffrent(listlist//

getDiffrent total times //

getDiffrent total times //

getDiffrent total times //

getDiffrent total times

}

/**

* 获取连个List的不同元素

* @param list

* @param list

* @return

*/

private static List<String> getDiffrent(List<String> list List<String> list) {

long st = SystemnanoTime()

Map<StringInteger> map = new HashMap<StringInteger>(listsize()+listsize())

List<String> diff = new ArrayList<String>()

List<String> maxList = list;

List<String> minList = list;

if(listsize()>listsize())

{

maxList = list;

minList = list;

}

for (String string : maxList) {

mapput(string

}

for (String string : minList) {

Integer cc = mapget(string)

if(cc!=null)

{

mapput(string ++cc)

continue;

}

mapput(string

}

for(MapEntry<String Integer> entry:mapentrySet())

{

if(entrygetValue()==

{

diffadd(entrygetKey())

}

}

Systemoutprintln(getDiffrent total times +(SystemnanoTime()st))

return diff;

}

/**

* 获取连个List的不同元素

* @param list

* @param list

* @return

*/

private static List<String> getDiffrent(List<String> list List<String> list) {

long st = SystemnanoTime()

Map<StringInteger> map = new HashMap<StringInteger>(listsize()+listsize())

List<String> diff = new ArrayList<String>()

for (String string : list) {

mapput(string

}

for (String string : list) {

Integer cc = mapget(string)

if(cc!=null)

{

mapput(string ++cc)

continue;

}

mapput(string

}

for(MapEntry<String Integer> entry:mapentrySet())

{

if(entrygetValue()==

{

diffadd(entrygetKey())

}

}

Systemoutprintln(getDiffrent total times +(SystemnanoTime()st))

return diff;

}

/**

* 获取连个List的不同元素

* @param list

* @param list

* @return

*/

private static List<String> getDiffrent(List<String> list List<String> list) {

long st = SystemnanoTime()

listretainAll(list

Systemoutprintln(getDiffrent total times +(SystemnanoTime()st))

return list;

}

/**

* 获取连个List的不同元素

* @param list

* @param list

* @return

*/

private static List<String> getDiffrent(List<String> list List<String> list) {

long st = SystemnanoTime()

List<String> diff = new ArrayList<String>()

for(String str:list

{

if(!ntains(str))

{

diffadd(str)

}

}

Systemoutprintln(getDiffrent total times +(SystemnanoTime()st))

return diff;

}}

这里对连个list的大小进行了判断小的在最后添加这样会减少循环里的判断性能又有了一定的提升正如一位朋友所说编程是无止境的只要你认真去思考了总会找到更好的方法!

上一篇:EJB之JPA(事务回滚)

下一篇:节点包含checkbox的Swing树控件