拿到这样一个问题,我可能会快速的写下代码,这里数组用arraylist.
private static void testlistset(){ list<string> arrays = new arraylist<string>(){ @override public boolean add(string e) { for(string str:this){ if(str.equals(e)){ system.out.println(add failed !!! duplicate element); return false; }else{ system.out.println(add successed !!!); } } return super.add(e); } }; arrays.add(a);arrays.add(b);arrays.add(c);arrays.add(b); for(string e:arrays) system.out.print(e); }
这里我什么都不关,只关心在数组添加元素的时候做下判断(当然添加数组元素只用add方法),是否已存在相同元素,如果数组中不存在这个元素,就添加到这个数组中,反之亦然。这样写可能简单,但是面临庞大数组时就显得笨拙:有100000元素的数组天家一个元素,难道要调用100000次equal吗?这里是个基础。
问题:加入已经有一些元素的数组了,怎么删除这个数组里重复的元素呢?
大家知道java中集合总的可以分为两大类:list与set。list类的集合里元素要求有序但可以重复,而set类的集合里元素要求无序但不能重复。那么这里就可以考虑利用set这个特性把重复元素删除不就达到目的了,毕竟用系统里已有的算法要优于自己现写的算法吧。
public static void removeduplicate(list<people> list){ hashset<people> set = new hashset<people>(list); list.clear(); list.addall(set); } ivate static people[] objdata = new people[]{ new people(0, a),new people(1, b),new people(0, a),new people(2, a),new people(3, c), };
public class people{ private int id; private string name; public people(int id,string name){ this.id = id; this.name = name; } @override public string tostring() { return (id = +id+ , name +name); } }
上面的代码,用了一个自定义的people类,当我添加相同的对象时候(指的是含有相同的数据内容),调用removeduplicate方法发现这样并不能解决实际问题,仍然存在相同的对象。那么hashset里是怎么判断像个对象是否相同的呢?打开hashset源码可以发现:每次往里面添加数据的时候,就必须要调用add方法:
@override public boolean add(e object) { return backingmap.put(object, this) == null; }
这里的backingmap也就是hashset维护的数据,它用了一个很巧妙的方法,把每次添加的object当作hashmap里面的key,本身hashset对象当作value。这样就利用了hashmap里的key***性,自然而然的hashset的数据不会重复。但是真正的是否有重复数据,就得看hashmap里的怎么判断两个key是否相同。
@override public v put(k key, v value) { 390 if (key == null) { 391 return putvaluefornullkey(value); 392 } 393 394 int hash = secondaryhash(key.hashcode()); 395 hashmapentry<k, v>[] tab = table; 396 int index = hash & (tab.length - 1); 397 for (hashmapentry<k, v> e = tab[index]; e != null; e = e.next) { 398 if (e.hash == hash && key.equals(e.key)) { 399 premodify(e); 400 v oldvalue = e.value; 401 e.value = value; 402 return oldvalue; 403 } 404 } 405 406 // no entry for (non-null) key is present; create one 407 modcount++; 408 if (size++ > threshold) { 409 tab = doublecapacity(); 410 index = hash & (tab.length - 1); 411 } 412 addnewentry(key, value, hash, index); 413 return null; 414 }
总的来说,这里实现的思路是:遍历hashmap里的元素,如果元素的hashcode相等(事实上还要对hashcode做一次处理),然后去判断key的eqaul方法。如果这两个条件满足,那么就是不同元素。那这里如果数组里的元素类型是自定义的话,要利用set的机制,那就得自己实现equal与hashmap(这里hashmap算法就不详细介绍了,我也就理解一点)方法了:
public class people{ private int id; // private string name; public people(int id,string name){ this.id = id; this.name = name; } @override public string tostring() { return (id = +id+ , name +name); } public int getid() { return id; } public void setid(int id) { this.id = id; } public string getname() { return name; } public void setname(string name) { this.name = name; } @override public boolean equals(object obj) { if(!(obj instanceof people)) return false; people o = (people)obj; if(id == o.getid()&&name.equals(o.getname())) return true; else return false; } @override public int hashcode() { // todo auto-generated method stub return id; //return super.hashcode(); } }
以上就是java如何删除数组中的重复元素的详细内容。
