怎么在百度建设一个网站,天津网站优化排名,奎文建设局网站,怎么使用源码建设网站问题当下互联网技术成熟#xff0c;越来越多的趋向去中心化、分布式、流计算#xff0c;使得很多以前在数据库侧做的事情放到了java端。今天有人问道#xff0c;如果数据库字段没有索引#xff0c;那么应该如何根据该字段去重#xff1f;大家都一致认为用java来做#xf…问题当下互联网技术成熟越来越多的趋向去中心化、分布式、流计算使得很多以前在数据库侧做的事情放到了java端。今天有人问道如果数据库字段没有索引那么应该如何根据该字段去重大家都一致认为用java来做但怎么做呢解答忽然想起以前写过list去重的文章找出来一看。做法就是将list中对象的hashcode和equals方法重写然后丢到hashset里然后取出来。这是最初刚学java的时候像被字典一样背写出来的答案。就比如面试面过号称做了3年java的人问set和hashmap的区别可以背出来问如何实现就不知道了。也就是说初学者只背特性。但真正在项目中使用的时候你需要确保一下是不是真的这样。因为背书没用只能相信结果。你需要知道hashset如何帮我做到去重了。换个思路不用hashset可以去重吗最简单最直接的办法不就是每次都拿着和历史数据比较都不相同则插入队尾。而hashset只是加速了这个过程而已。首先给出我们要排序的对象userdatabuilderallargsconstructorpublic class user {private integer id;private string name;}list users lists.newarraylist(new user(1, a),new user(1, b),new user(2, b),new user(1, a));目标是取出id不重复的user为了防止扯皮给个规则只要任意取出id唯一的数据即可不用拘泥id相同时算哪个。用最直观的办法这个办法就是用一个空list存放遍历后的数据。testpublic void dis1() {list result new linkedlist();for (user user : users) {boolean b result.stream().anymatch(u - u.getid().equals(user.getid()));if (!b) {result.add(user);}}system.out.println(result);}用hashset背过特性的都知道hashset可以去重那么是如何去重的呢 再深入一点的背过根据hashcode和equals方法。那么如何根据这两个做到的呢没有看过源码的人是无法继续的面试也就到此结束了。事实上hashset是由hashmap来实现的(没有看过源码的时候曾经一直直观的以为hashmap的key是hashset来实现的恰恰相反)。这里不展开叙述只要看hashset的构造方法和add方法就能理解了。public hashset() {map new hashmap();}/*** 显然存在则返回false不存在的返回true*/public boolean add(e e) {return map.put(e, present)null;}那么由此也可以看出hashset的去重复就是根据hashmap实现的而hashmap的实现又完全依赖于hashcode和equals方法。这下就彻底打通了想用hashset就必须看好自己的这两个方法。在本题目中要根据id去重那么我们的比较依据就是id了。修改如下overridepublic boolean equals(object o) {if (this o) {return true;}if (o null || getclass() ! o.getclass()) {return false;}user user (user) o;return objects.equals(id, user.id);}overridepublic int hashcode() {return objects.hash(id);}//hashcoderesult 31 * result (element null ? 0 : element.hashcode());其中 objects调用arrays的hashcode内容如上述所示。乘以31等于x5-x。最终实现如下testpublic void dis2() {set result new hashset(users);system.out.println(result);}使用java的stream去重回到最初的问题之所以提这个问题是因为想要将数据库侧去重拿到java端那么数据量可能比较大比如10w条。对于大数据采用stream相关函数是最简单的了。正好stream也提供了distinct函数。那么应该怎么用呢users.parallelstream().distinct().foreach(system.out::println);没看到用lambda当作参数也就是没有提供自定义条件。幸好javadoc标注了去重标准returns a stream consisting of the distinct elements(according to {link object#equals(object)}) of this stream.我们知道也必须背过这样一个准则equals返回true的时候hashcode的返回值必须相同. 这个在背的时候略微有些逻辑混乱但只要了解了hashmap的实现方式就不会觉得拗口了。hashmap先根据hashcode方法定位再比较equals方法。所以要使用distinct来实现去重必须重写hashcode和equals方法除非你使用默认的。那么究竟为啥要这么做点进去看一眼实现。 node reduce(pipelinehelper helper, spliterator spliterator) {// if the stream is sorted then it should also be ordered so the following will also// preserve the sort orderterminalop reduceop reduceops.makeref(linkedhashset::new, linkedhashset::add, linkedhashset::addall);return nodes.node(reduceop.evaluateparallel(helper, spliterator));}内部是用reduce实现的啊想到reduce瞬间想到一种自己实现distinctbykey的方法。我只要用reduce计算部分就是把stream的元素拿出来和我自己内置的一个hashmap比较有则跳过没有则放进去。其实思路还是最开始的那个最直白的方法。testpublic void dis3() {users.parallelstream().filter(distinctbykey(user::getid)).foreach(system.out::println);}public static predicate distinctbykey(function super t, ? keyextractor) {set seen concurrenthashmap.newkeyset();return t - seen.add(keyextractor.apply(t));}当然如果是并行stream则取出来的不一定是第一个而是随机的。上述方法是至今发现最好的无侵入性的。但如果非要用distinct。只能像hashset那个方法一样重写hashcode和equals。小结会不会用这些东西你只能去自己练习过不然到了真正要用的时候很难一下子就拿出来不然就冒险用。而若真的想大胆使用了解规则和实现原理也是必须的。比如linkedhashset和hashset的实现有何不同。附上贼简单的linkedhashset源码public class linkedhashsetextends hashsetimplements set, cloneable, java.io.serializable {private static final long serialversionuid -2851667679971038690l;public linkedhashset(int initialcapacity, float loadfactor) {super(initialcapacity, loadfactor, true);}public linkedhashset(int initialcapacity) {super(initialcapacity, .75f, true);}public linkedhashset() {super(16, .75f, true);}public linkedhashset(collection extends e c) {super(math.max(2*c.size(), 11), .75f, true);addall(c);}overridepublic spliterator spliterator() {return spliterators.spliterator(this, spliterator.distinct | spliterator.ordered);}}补充java中list集合去除重复数据的方法1. 循环list中的所有元素然后删除重复public static list removeduplicate(list list) {for ( int i 0 ; i list.size() - 1 ; i ) {for ( int j list.size() - 1 ; j i; j -- ) {if (list.get(j).equals(list.get(i))) {list.remove(j);}}}return list;}2. 通过hashset踢除重复元素public static list removeduplicate(list list) {hashset h new hashset(list);list.clear();list.addall(h);return list;}3. 删除arraylist中重复元素保持顺序// 删除arraylist中重复元素保持顺序public static void removeduplicatewithorder(list list) {set set new hashset();list newlist new arraylist();for (iterator iter list.iterator(); iter.hasnext();) {object element iter.next();if (set.add(element))newlist.add(element);}list.clear();list.addall(newlist);system.out.println( remove duplicate list);}4.把list里的对象遍历一遍用list.contain()如果不存在就放入到另外一个list集合中public static list removeduplicate(list list){list listtemp new arraylist();for(int i0;iif(!listtemp.contains(list.get(i))){listtemp.add(list.get(i));}}return listtemp;}如您对本文有疑问或者有任何想说的请点击进行留言回复万千网友为您解惑