Java集合List介绍和去重方案

简介: Java集合List介绍和去重方案

1 List集合概述和特点

List集合概述:

  • 有序集合(也称为序列),用户可以精确控制列表中每个元素的插入位置。用户可以通过整数索引访问元素,并搜索列表中的元素Set集合不同,列表通常允许重复的元素

List集合特点:

  • 有索引
  • 可以存储重复元素
  • 元素存取有序

2 List集合的特有方法

3 集合的案例-List集合存储学生对象并遍历

案例需求

创建一个存储学生对象的集合,存储3个学生对象,使用程序实现在控制台遍历该集合

代码实现

学生类

public class Student {
    private String name;
    private int age;
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

测试类

public class ListDemo {
    public static void main(String[] args) {
//创建List集合对象
        List<Student> list = new ArrayList<Student>();
//创建学生对象
        Student s1 = new Student("林青霞", 30);
        Student s2 = new Student("张曼玉", 35);
        Student s3 = new Student("王祖贤", 33);
//把学生添加到集合
        list.add(s1);
        list.add(s2);
        list.add(s3);
//迭代器方式
        Iterator<Student> it = list.iterator();
        while (it.hasNext()) {
            Student s = it.next();
            System.out.println(s.getName() + "," + s.getAge());
        }
        System.out.println("--------");
//for循环方式
        for(int i=0; i<list.size(); i++) {
            Student s = list.get(i);
            System.out.println(s.getName() + "," + s.getAge());
        }
    }
}

4 并发修改异常

 

出现的原因:

  • 迭代器遍历的过程中,通过集合对象修改了集合中的元素,造成了迭代器获取元素中判断预期修改值和实际
  • 修改值不一致,则会出现:ConcurrentModifificationException

解决的方案:

  • for循环遍历,然后用集合对象做对应的操作即可

示例代码

public class ListDemo {
    public static void main(String[] args) {
//创建集合对象
        List<String> list = new ArrayList<String>();
//添加元素
        list.add("hello");
        list.add("world");
        list.add("java");
//遍历集合,得到每一个元素,看有没有"world"这个元素,如果有,我就添加一
        个"javaee"元素,请写代码实现
// Iterator<String> it = list.iterator();
// while (it.hasNext()) {
// String s = it.next();
// if(s.equals("world")) {
// list.add("javaee");
// }
// }
        for(int i=0; i<list.size(); i++) {
            String s = list.get(i);
            if(s.equals("world")) {
                list.add("javaee");
            }
        }
//输出集合对象
        System.out.println(list);
    }
}

5 列表迭代器

ListIterator 介绍

通过 List 集合的 listIterator() 方法得到,所以说它是 List 集合特有的迭代器

用于允许程序员沿任一方向遍历的列表迭代器,在迭代期间修改列表,并获取列表中迭代器的当前位置

示例代码

public class ListIteratorDemo {
    public static void main(String[] args) {
//创建集合对象
        List<String> list = new ArrayList<String>();
//添加元素
        list.add("hello");
        list.add("world");
        list.add("java");
//获取列表迭代器
        ListIterator<String> lit = list.listIterator();
        while (lit.hasNext()) {
            String s = lit.next();
            if(s.equals("world")) {
                lit.add("javaee");
            }
        }
        System.out.println(list);
    }
}

6 增强for循环

1. for(元素数据类型 变量名 : 数组/集合对象名) {
2. 循环体;
3. }

示例代码

public class ForDemo {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
        for(int i : arr) {
            System.out.println(i);
        }
        System.out.println("--------");
        String[] strArray = {"hello","world","java"};
        for(String s : strArray) {
            System.out.println(s);
        }
        System.out.println("--------");
        List<String> list = new ArrayList<String>();
        list.add("hello");
        list.add("world");
        list.add("java");
        for(String s : list) {
            System.out.println(s);
        }
        System.out.println("--------");
//内部原理是一个Iterator迭代器
/*
for(String s : list) {
if(s.equals("world")) {
list.add("javaee"); //ConcurrentModificationException
}
}
*/
    }
}

7 数据结构

7.1 数据结构之栈和队列

栈结构:

  • 先进后出
  • 队列结构
  • 先进先出

7.2 数据结构之数组和链表

数组结构:

  • 查询快、增删慢

队列结构:

  • 查询慢、增删快

8. List集合的实现类

8.1 List集合子类的特点

ArrayList 集合:

底层是数组结构实现,查询快、增删慢

LinkedList 集合:

  • 底层是链表结构实现,查询慢、增删快

8.2 集合的案例-ArrayList集合存储学生对象三种方式遍历

案例需求

创建一个存储学生对象的集合,存储 3 个学生对象,使用程序实现在控制台遍历该集合

代码实现

学生类

public class Student {
    private String name;
    private int age;
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

测试类

public class ArrayListDemo {
    public static void main(String[] args) {
//创建ArrayList集合对象
        ArrayList<Student> array = new ArrayList<Student>();
//创建学生对象
        Student s1 = new Student("林青霞", 30);
        Student s2 = new Student("张曼玉", 35);
        Student s3 = new Student("王祖贤", 33);
//把学生添加到集合
        array.add(s1);
        array.add(s2);
        array.add(s3);
//迭代器:集合特有的遍历方式
        Iterator<Student> it = array.iterator();
        while (it.hasNext()) {
            Student s = it.next();
            System.out.println(s.getName() + "," + s.getAge());
        }
        System.out.println("--------");
//普通for:带有索引的遍历方式
        for(int i=0; i<array.size(); i++) {
            Student s = array.get(i);
            System.out.println(s.getName() + "," + s.getAge());
        }
        System.out.println("--------");
//增强for:最方便的遍历方式
        for(Student s : array) {
            System.out.println(s.getName() + "," + s.getAge());
        }
    }
}


8.3 LinkedList集合的特有功能

9 java8中List根据某一字段去重

实体类:

package test;
public class User {
    private String userid;
    private String username;
    private String age;
    private String address;
    public User(String userid, String username, String age, String address) {
        super();
        this.userid = userid;
        this.username = username;
        this.age = age;
        this.address = address;
    }
    public String getUserid() {
        return userid;
    }
    public void setUserid(String userid) {
        this.userid = userid;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    @Override
    public String toString() {
        return "User [userid=" + userid + ", username=" + username + ", age=" + age + ", address=" + address + "]";
    }
}

测试:

package test;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;
public class Test1 {
    public static void main(String[] args) {
        List<User> userList = new ArrayList<>();
        userList.add(new User("1","李大锤","23","南京"));
        userList.add(new User("2","张无忌","18","西安"));
        userList.add(new User("3","刘德华","26","苏州"));
        userList.add(new User("4","郭靖","33","上海"));
        userList.add(new User("1","李大锤","23","南京"));    //id相同,其他数据也相同
        userList.add(new User("3","带头大哥","36","杭州"));  //id相同,其他数据不同
        System.out.println(userList);
        //根据userid去重
        userList = userList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User :: getUserid))), ArrayList::new));
        System.out.println(userList);
    }
}

测试结果:

[User [userid=1, username=李大锤, age=23, address=南京], User [userid=2, username=张无忌, age=18, address=西安], User [userid=3, username=刘德华, age=26, address=苏州], User [userid=4, username=郭靖, age=33, address=上海], User [userid=1, username=李大锤, age=23, address=南京], User [userid=3, username=带头大哥, age=36, address=杭州]]
[User [userid=1, username=李大锤, age=23, address=南京], User [userid=2, username=张无忌, age=18, address=西安], User [userid=3, username=刘德华, age=26, address=苏州], User [userid=4, username=郭靖, age=33, address=上海]]

可以看出,此操作把后面的两个id相同的都给剔除了。若两个id一样,其他数据不同的话,留下的数据是靠前的数据,剔除的是靠后的数据。

10 list简单去重

方案一:借助Set的特性进行去重

  /**
     * 去除重复数据
     * 由于Set的无序性,不会保持原来顺序
     * @param list
     */
    public static List<String> list distinct(List<String> list) {
        final boolean sta = null != list && list.size() > 0;
        List doubleList= new ArrayList();
        if (sta) {
            Set set = new HashSet();
            set.addAll(list);
            doubleList.addAll(set);
        }
        return doubleList;
    }

方案二 : 利用set集合特性保持顺序一致去重

// Set去重并保持原先顺序的两种方法
   public static void delRepeat(List<String> list) {
       //方法一
       List<String> listNew = new ArrayList<String>(new TreeSet<String>(list));
       //方法二
       List<String> listNew2 = new ArrayList<String>(new LinkedHashSet<String>(list));
   }

方案三 : 使用list自身方法remove()–>不推荐

    /**
     * 去除重复数据(一般不推荐)
     * 类似于冒泡排序思想
     * @param list
     */
  public static List<Map<String, Object>> distinct(List<Map<String, Object>> list) {
        if (null != list && list.size() > 0) {
        //循环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);
                    }
                }
            }
        }
        //得到最新移除重复元素的list
        return list;
    }

方案四 : 遍历List集合,将元素添加到另一个List集合中

// 遍历后判断赋给另一个list集合,保持原来顺序
public static List<String> delRepeat(List<String> list) {
    List<String> listNew = new ArrayList<String>();
    for (String str : list) {
         if (!listNew.contains(str)) {
             listNew.add(str);
         }
     }
    return listNew ;
}

方案5 : 使用Java8特性去重

public static List<String> delRepeat(List<String> list) {
     List<String> myList = list.stream().distinct().collect(Collectors.toList());
   return myList ;
}


目录
相关文章
|
1月前
|
Java
【Java】如果一个集合中类型是String如何使用拉姆达表达式 进行Bigdecimal类型计算?
【Java】如果一个集合中类型是String如何使用拉姆达表达式 进行Bigdecimal类型计算?
25 0
|
28天前
|
Java
java8中List对象转另一个List对象
java8中List对象转另一个List对象
37 0
|
1天前
|
存储 Java
Java中利用BitMap位图实现海量级数据去重
Java中利用BitMap位图实现海量级数据去重
|
2天前
|
消息中间件 NoSQL 算法
Java中常见延时队列的实现方案总结
Java中常见延时队列的实现方案总结
|
3天前
|
存储 Java C++
Java集合篇之深度解析Queue,单端队列、双端队列、优先级队列、阻塞队列
Java集合篇之深度解析Queue,单端队列、双端队列、优先级队列、阻塞队列
17 0
|
15天前
|
存储 Java 编译器
Java集合丛林:深入了解集合框架的秘密
Java集合丛林:深入了解集合框架的秘密
16 0
Java集合丛林:深入了解集合框架的秘密
|
18天前
|
Java BI
Java 获取周,月,年日期集合(统计图)
Java 获取周,月,年日期集合(统计图)
Java 获取周,月,年日期集合(统计图)
|
25天前
|
Java
Java使用List去重的四中方式
Java使用List去重的四中方式
19 6
|
29天前
|
存储 安全 Java
【Java技术专题】「Guava开发指南」手把手教你如何进行使用Guava工具箱进行开发系统实战指南(不可变集合篇)
【Java技术专题】「Guava开发指南」手把手教你如何进行使用Guava工具箱进行开发系统实战指南(不可变集合篇)
30 1
|
29天前
Cause: java.sql.SQLIntegrityConstraintViolationException: Column ‘id‘ in field list is ambiguous
Cause: java.sql.SQLIntegrityConstraintViolationException: Column ‘id‘ in field list is ambiguous
18 0