java中List对象列表去重或取出以及排序

简介:

面试碰到几次list的去重和排序。下面介绍一种做法:

1. list去重

1.1 实体类Student

List<Student>容量10k以上,要求去重复。这里Student的重复标准是属性相同,因此需要重写equals和hashcode方法,不知道有几个可以手写出来。

student的equals方法:

  View Code

这里只要记住宗旨是比较Student的属性即可,如果属性相同则相等。先考虑地址相等,然后类型匹配instanceof。接下来是各种属性,int属性直接双等号比较,String类型需要判断是否为null,如果是null则都是null返回true,如果不是null则比较equals。

student的hashcode方法:

  View Code

hashCode是为了hash表计算做辅助,方便快速查找。因此hash算法的结果要尽量的散列。这里用到31,这个31在别的博客中看到的原因是这样的:obj*31==obj<<5-obj.左移5位相当乘以2的5次方,就是32.null的hashCode为空。

通过equals和hashCode的实现可以发现,如果equals为true,则所有属性相同,而属性相同则计算出的hashCode必然相同。然而hashCode相同,属性未必一样,即equals不一定为真。

关于hashCode的价值体现并不在这里,而在于HashMap的实现。HashMap内部是通过链表数组的hash结构来实现的,这里就要用到hashcode。

下面是完整的Student代码:

  View Code

1.2通过HashSet去重

如果你觉得自己可以hold住一个完善的hash算法就可以自己去实现它。这里采用jdk自带的HashSet来完成重复获取。

先放代码:

  View Code

去重的原理和简单,无论你仅仅是想把重复的丢掉,或者将重复的取出来。这里去掉的是第二次遇到的对象,取出的也是第二次遇到的对象。HashSet中的add方法会返回一个Boolean值,如果插入的值已经存在,则直接返回false。关于hashset的源码放到以后研究。大概的说,是通过HashMap的key来实现的,而HashMap在1.8中改动很大,据说是用红黑树实现的,提高了get的时间复杂度。参考:1.8HashMap

 

2. list对象排序

同样list中存放的是Student对象,我需要一个规则来排序。这个排序的规则这里定义为id的比较大小。参考:java中list排序

2.1 Student对象实现Comparable接口

Comparable接口提供一个比较的compareTo(Object o)方法,通过返回值>0,=0,<0比较大小。这里由于仅仅把id当做比较大小的方法,直接用id做减法,如果是要比较对象,建议套用this.property.compareTo(o.property).

  View Code

通过Collections.sort(list)排序:

  View Code

2.2 重载sort方法,传入一个比较器

Student类还是未实现Comparable接口之前的:

  View Code

在排序的代码出添加排序规则:

复制代码
package com.test.arithmetic.list.sort;

import com.test.arithmetic.list.Student;
import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * 对list中对象排序
 * Created by Administrator on 2016/3/29.
 */
public class SortList {
    List<Student> list;
    @Before
    public void setUp(){
        list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            int v = (int)(Math.random() * 100);
            list.add(new Student(v,"_"+v,18+v));
        }
        System.out.println("原list:"+list);
    }
    //方法一,对象实现Comparable接口
    @Test
    public void byImplements(){
//        Collections.sort(list);
        System.out.println("排序后:"+list);
    }

    /*方法二,添加比较器*/
    @Test
    public void byOverideCompare(){

        Collections.sort(list, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getId()-o2.getId();
            }
        });
        System.out.println(list);
    }
}
复制代码

 

本文转自Ryan.Miao博客园博客,原文链接:http://www.cnblogs.com/woshimrf/p/5334689.html,如需转载请自行联系原作者
相关文章
|
3天前
|
XML JavaScript 数据格式
DOM 节点列表长度(Node List Length)
`length`属性用于获取DOM节点列表的元素数量。在示例中,加载&quot;books.xml&quot;后,通过getElementsByTagName(&quot;title&quot;)获取标题节点列表,然后使用`for`循环遍历列表,输出每个标题的文本内容。此代码演示了如何处理XML文档中的节点集合。
|
5天前
|
消息中间件 Java Kafka
Java大文件排序(有手就能学会),kafka面试题2024
Java大文件排序(有手就能学会),kafka面试题2024
|
6天前
|
存储 算法 搜索推荐
【Java高阶数据结构】图补充-拓扑排序
【Java高阶数据结构】图补充-拓扑排序
7 1
|
6天前
|
JavaScript
DOM 节点列表长度(Node List Length)
`length`属性用于获取DOM节点列表的长度,允许遍历和处理节点。例如,加载&quot;books.xml&quot;到`xmlDoc`,通过`getElementsByTagName(&quot;title&quot;)`获取所有标题节点,然后使用循环输出每个&lt;title&gt;元素的文本内容。
|
6天前
|
存储 安全 算法
Java一分钟之-Java集合框架入门:List接口与ArrayList
【5月更文挑战第10天】本文介绍了Java集合框架中的`List`接口和`ArrayList`实现类。`List`是有序集合,支持元素重复并能按索引访问。核心方法包括添加、删除、获取和设置元素。`ArrayList`基于动态数组,提供高效随机访问和自动扩容,但非线程安全。文章讨论了三个常见问题:索引越界、遍历时修改集合和并发修改,并给出避免策略。通过示例代码展示了基本操作和安全遍历删除。理解并正确使用`List`和`ArrayList`能提升程序效率和稳定性。
12 0
|
6天前
|
存储 安全 Java
【JAVA基础篇教学】第八篇:Java中List详解说明
【JAVA基础篇教学】第八篇:Java中List详解说明
|
6天前
|
存储 安全 Java
Java容器类List、ArrayList、Vector及map、HashTable、HashMap
Java容器类List、ArrayList、Vector及map、HashTable、HashMap
|
6天前
|
XML 数据格式
节点列表长度(Node List Length)
`NodeList`对象自动更新,其`length`属性表示列表中节点数量。例如,加载&quot;books.xml&quot;后,`getElementsByTagName(&#39;title&#39;).length`返回`4`。此属性可用来遍历列表,如示例所示,遍历所有`&lt;title&gt;`元素并打印其文本内容:Everyday Italian, Harry Potter, XQuery Kick Start, Learning XML。
|
6天前
|
Python
【Python 基础】列表(list)和元组(tuple)有什么区别?
【5月更文挑战第6天】【Python 基础】列表(list)和元组(tuple)有什么区别?
|
1天前
|
安全 Java 程序员
深入理解Java并发编程:线程安全与性能优化
【5月更文挑战第20天】本文将深入探讨Java并发编程的核心概念,包括线程安全和性能优化。我们将详细解析synchronized关键字、ReentrantLock类以及java.util.concurrent包中的高级工具类,如Semaphore、CountDownLatch和CyclicBarrier等。通过实例演示如何使用这些工具来提高多线程程序的性能和可靠性。