这几天在写代码时候用到了关于ArrayList的一些算法,在这里整理一下。有点小感悟:现在逐渐明白为什么大公司对算法的要求这么高,在写代码逻辑的时候就是用算法处理,而算法的效率的高低直接决定了你程序的运行性能,看来在以后的训练中药加强对算法的训练呀。
首先看一下CollectionUtils这个Collection工具类对list的一些处理,摘了别人的代码,把运行结果贴出来:
package com.web.test; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.ArrayUtils; public class CollectionUtilsTest { @SuppressWarnings("unchecked") public static void main(String[] args) { List<String> aList = new ArrayList<String>(); aList.add("aaa"); aList.add("bbb"); aList.add("ccc"); List<String> bList = new ArrayList<String>(); bList.add("aaa"); bList.add("ddd"); bList.add("eee"); // 并集 Collection<String> unionList = CollectionUtils.union(aList, bList); // 交集 Collection<String> intersectionList = CollectionUtils.intersection(aList, bList); // 是否存在交集 boolean isContained = CollectionUtils.containsAny(aList, bList); // 交集的补集 Collection<String> disjunctionList = CollectionUtils.disjunction(aList, bList); // 集合相减 Collection<String> subtractList = CollectionUtils.subtract(aList, bList); // 排序 Collections.sort((List<String>) unionList); Collections.sort((List<String>) intersectionList); Collections.sort((List<String>) disjunctionList); Collections.sort((List<String>) subtractList); // 测试 System.out.println("A: " + ArrayUtils.toString(aList.toArray())); System.out.println("B: " + ArrayUtils.toString(bList.toArray())); System.out.println("A has one of B? : " + isContained); System.out.println("Union(A, B): " + ArrayUtils.toString(unionList.toArray())); System.out.println("Intersection(A, B): "+ ArrayUtils.toString(intersectionList.toArray())); System.out.println("Disjunction(A, B): " + ArrayUtils.toString(disjunctionList.toArray())); System.out.println("Subtract(A, B): "+ ArrayUtils.toString(subtractList.toArray())); } }
现在看一下他的源码实现:
首先是union:
public static Collection union(final Collection a, final Collection b) { ArrayList list = new ArrayList(); Map mapa = getCardinalityMap(a); Map mapb = getCardinalityMap(b); Set elts = new HashSet(a); elts.addAll(b); Iterator it = elts.iterator(); while(it.hasNext()) { Object obj = it.next(); for(int i=0,m=Math.max(getFreq(obj,mapa),getFreq(obj,mapb));i<m;i++) { list.add(obj); } } return list; }
再是intersection:
public static Collection intersection(final Collection a, final Collection b) { ArrayList list = new ArrayList(); Map mapa = getCardinalityMap(a); Map mapb = getCardinalityMap(b); Set elts = new HashSet(a); elts.addAll(b); Iterator it = elts.iterator(); while(it.hasNext()) { Object obj = it.next(); for(int i=0,m=Math.min(getFreq(obj,mapa),getFreq(obj,mapb));i<m;i++) { list.add(obj); } } return list; }
对于交集的处理同样也是基于set和map的。关于其他实现,大家可以参照源码,从上边这两段代码来看,效率并不高毕竟它是相当于遍历两个list,时间复杂度应该是n*n。需要说明的是这些方法都是数学的集合算法。
对于比较两个链表可以在ArrayList中处理,也可以在HashMap中处理,现在给出这两中处理方式:
import java.util.Collection; import java.util.ArrayList; import java.util.Arrays; public class Repeated { public static void main( String [] args ) { Collection listOne = new ArrayList(Arrays.asList("milan","dingo", "elpha", "hafil", "meat", "iga", "neeta.peeta")); Collection listTwo = new ArrayList(Arrays.asList("hafil", "iga", "binga", "mike", "dingo")); listOne.retainAll( listTwo ); System.out.println( listOne ); } }
再看一下HashMap的处理方式:
import java.util.Collection; import java.util.HashSet; import java.util.Arrays; class Repeated { public static void main( String [] args ) { Collection<String> listOne = Arrays.asList("milan","iga","dingo","iga","elpha","iga"); Collection<String> listTwo = Arrays.asList("hafil", "iga","dingo","dingo","dingo"); Collection<String> similar = new HashSet<String>( listOne ); Collection<String> different = new HashSet<String>(); different.addAll( listOne ); different.addAll( listTwo ); similar.retainAll( listTwo ); different.removeAll( similar ); System.out.printf(listOne, listTwo, similar, different); } }
或者不用集合,自己直接对这两个list进行处理:
private static ArrayList<String> getSame(ArrayList<String> list1, ArrayList<String> list2){ ArrayList<String> diff = new ArrayList<String>(); for(String str:list1){ if(list2.contains(str)) { diff.add(str); } } return diff; }
这里有一篇讲集合非常好的文章,大家可以参考一下https://www3.ntu.edu.sg/home/ehchua/programming/java/J5c_Collection.html