java中删除数组中重复元素方法探讨
问题:比如我有一个数组(元素个数为0哈),希望添加进去元素不能重复。
拿到这样一个问题,我可能会快速的写下代码,这里数组用ArrayList.
privatestaticvoidtestListSet(){
List<String>arrays=newArrayList<String>(){
@Override
publicbooleanadd(Stringe){
for(Stringstr:this){
if(str.equals(e)){
System.out.println("addfailed!!! duplicateelement");
returnfalse;
}else{
System.out.println("addsuccessed!!!");
}
}
returnsuper.add(e);
}
};
arrays.add("a");arrays.add("b");arrays.add("c");arrays.add("b");
for(Stringe:arrays)
System.out.print(e);
}
这里我什么都不关,只关心在数组添加元素的时候做下判断(当然添加数组元素只用add方法),是否已存在相同元素,如果数组中不存在这个元素,就添加到这个数组中,反之亦然。这样写可能简单,但是面临庞大数组时就显得笨拙:有100000元素的数组天家一个元素,难道要调用100000次equal吗?这里是个基础。
问题:加入已经有一些元素的数组了,怎么删除这个数组里重复的元素呢?
大家知道java中集合总的可以分为两大类:List与Set。List类的集合里元素要求有序但可以重复,而Set类的集合里元素要求无序但不能重复。那么这里就可以考虑利用Set这个特性把重复元素删除不就达到目的了,毕竟用系统里已有的算法要优于自己现写的算法吧。
publicstaticvoidremoveDuplicate(List<People>list){
HashSet<People>set=newHashSet<People>(list);
list.clear();
list.addAll(set);
} privatestaticPeople[]ObjData=newPeople[]{
newPeople(0,"a"),newPeople(1,"b"),newPeople(0,"a"),newPeople(2,"a"),newPeople(3,"c"),
};
上面的代码,用了一个自定义的People类,当我添加相同的对象时候(指的是含有相同的数据内容),调用removeDuplicate方法发现这样并不能解决实际问题,仍然存在相同的对象。那么HashSet里是怎么判断像个对象是否相同的呢?打开HashSet源码可以发现:每次往里面添加数据的时候,就必须要调用add方法: 这里的backingMap也就是HashSet维护的数据,它用了一个很巧妙的方法,把每次添加的Object当作HashMap里面的KEY,本身HashSet对象当作VALUE。这样就利用了Hashmap里的KEY唯一性,自然而然的HashSet的数据不会重复。但是真正的是否有重复数据,就得看HashMap里的怎么判断两个KEY是否相同。 inthash=secondaryHash(key.hashCode()); //Noentryfor(non-null)keyispresent;createone 总的来说,这里实现的思路是:遍历hashmap里的元素,如果元素的hashcode相等(事实上还要对hashcode做一次处理),然后去判断KEY的eqaul方法。如果这两个条件满足,那么就是不同元素。那这里如果数组里的元素类型是自定义的话,要利用Set的机制,那就得自己实现equal与hashmap(这里hashmap算法就不详细介绍了,我也就理解一点)方法了: publicvoidsetId(intid){ publicStringgetName(){ publicvoidsetName(Stringname){ @Override 这里在调用removeDuplicate(list)方法就不会出现两个相同的people了。 好吧,这里就测试它们的性能吧: publicstaticvoidremoveDuplicateWithOrder(List<String>arlList) //loopthroughtheoriginalarray... //ifwedidn"tfindaduplicate,addthenewelementtothenewarray } 测试结果:
publicclassPeople{
privateintid;
privateStringname;
publicPeople(intid,Stringname){
this.id=id;
this.name=name;
}
@Override
publicStringtoString(){
return("id="+id+",name"+name);
}
}
@Override
publicbooleanadd(Eobject){
returnbackingMap.put(object,this)==null;
}
@OverridepublicVput(Kkey,Vvalue){
if(key==null){
returnputValueForNullKey(value);
}
HashMapEntry<K,V>[]tab=table;
intindex=hash&(tab.length-1);
for(HashMapEntry<K,V>e=tab[index];e!=null;e=e.next){
if(e.hash==hash&&key.equals(e.key)){
preModify(e);
VoldValue=e.value;
e.value=value;
returnoldValue;
}
}
modCount++;
if(size++>threshold){
tab=doubleCapacity();
index=hash&(tab.length-1);
}
addNewEntry(key,value,hash,index);
returnnull;
}
publicclassPeople{
privateintid;//
privateStringname;
publicPeople(intid,Stringname){
this.id=id;
this.name=name;
}
@Override
publicStringtoString(){
return("id="+id+",name"+name);
}
publicintgetId(){
returnid;
}
this.id=id;
}
returnname;
}
this.name=name;
}
publicbooleanequals(Objectobj){
if(!(objinstanceofPeople))
returnfalse;
Peopleo=(People)obj;
if(id==o.getId()&&name.equals(o.getName()))
returntrue;
else
returnfalse;
}
@Override
publicinthashCode(){
//TODOAuto-generatedmethodstub
returnid;
//returnsuper.hashCode();
}
}
publicclassRemoveDeplicate{
publicstaticvoidmain(String[]args){
//TODOAuto-generatedmethodstub
//testListSet();
//removeDuplicateWithOrder(Arrays.asList(data));
//ArrayList<People>list=newArrayList<People>(Arrays.asList(ObjData));
//removeDuplicate(list);
People[]data=createObjectArray(10000);
ArrayList<People>list=newArrayList<People>(Arrays.asList(data));
longstartTime1=System.currentTimeMillis();
System.out.println("setstarttime-->"+startTime1);
removeDuplicate(list);
longendTime1=System.currentTimeMillis();
System.out.println("setendtime--> "+endTime1);
System.out.println("settotaltime--> "+(endTime1-startTime1));
System.out.println("count:"+People.count);
People.count=0;
longstartTime=System.currentTimeMillis();
System.out.println("Efficientstarttime-->"+startTime);
EfficientRemoveDup(data);
longendTime=System.currentTimeMillis();
System.out.println("Efficientendtime--> "+endTime);
System.out.println("Efficienttotaltime--> "+(endTime-startTime));
System.out.println("count:"+People.count);
}
publicstaticvoidremoveDuplicate(List<People>list)
{
HashSet<People>set=newHashSet<People>(list);
list.clear();
list.addAll(set);
}
{
Set<String>set=newHashSet<String>();
List<String>newList=newArrayList<String>();
for(Iterator<String>iter=arlList.iterator();iter.hasNext();){
Stringelement=iter.next();
if(set.add(element))
newList.add(element);
}
arlList.clear();
arlList.addAll(newList);
}
@SuppressWarnings("serial")
privatestaticvoidtestListSet(){
List<String>arrays=newArrayList<String>(){
@Override
publicbooleanadd(Stringe){
for(Stringstr:this){
if(str.equals(e)){
System.out.println("addfailed!!! duplicateelement");
returnfalse;
}else{
System.out.println("addsuccessed!!!");
}
}
returnsuper.add(e);
}
};
arrays.add("a");arrays.add("b");arrays.add("c");arrays.add("b");
for(Stringe:arrays)
System.out.print(e);
}
privatestaticvoidEfficientRemoveDup(People[]peoples){
//Object[]originalArray;//again,pretendthiscontainsouroriginaldata
intcount=0;
//newtemporaryarraytoholdnon-duplicatedata
People[]newArray=newPeople[peoples.length];
//currentindexinthenewarray(alsothenumberofnon-dupelements)
intcurrentIndex=0;
for(inti=0;i<peoples.length;++i){
//contains=>trueiffnewArraycontainsoriginalArray[i]
booleancontains=false;
//searchthroughnewArraytoseeifitcontainsanelementequal
//totheelementinoriginalArray[i]
for(intj=0;j<=currentIndex;++j){
//ifthesameelementisfound,don"taddittothenewarray
count++;
if(peoples[i].equals(newArray[j])){
contains=true;
break;
}
}
if(!contains){
//note:youmaywanttouseacopyconstructor,ora.clone()
//hereifthesituationwarrantsmorethanashallowcopy
newArray[currentIndex]=peoples[i];
++currentIndex;
}
}
System.out.println("efficientmedthodinner count:"+count);
privatestaticPeople[]createObjectArray(intlength){
intnum=length;
People[]data=newPeople[num];
Randomrandom=newRandom();
for(inti=0;i<num;i++){
intid=random.nextInt(10000);
System.out.print(id+"");
data[i]=newPeople(id,"iamaman");
}
returndata;
}
}
setendtime--> 1326443326724
settotaltime--> 26
count:3653
Efficientstarttime-->1326443326729
efficientmedthodinner count:28463252
Efficientendtime--> 1326443327107
Efficienttotaltime--> 378
count:28463252
相关文章