【java】集合类

简介: 【java】集合类

集合根接口

所有的集合类最终都是实现自集合根接口的,比如ArrayList类,它的祖先就是Collection接口

LIST列表

import java.util.ArrayList;   //集合类基本都是在java.util包下定义的
public class Main {
    public static void main(String[] args) {
        //List<String> list = new ArrayList<>();
        ArrayList<String> list = new ArrayList<>();
        list.add("中文");
        list.add(0,"coleak");
        list.add("9");
        list.add("cc");
        list.add("ay");
        list.sort(String::compareTo);
        System.out.println(list);
        System.out.println(list.contains("coleak"));
        System.out.println(list.get(2));
        System.out.println(list.remove("colea"));
        System.out.println(list.remove("coleak"));
        System.out.println(list.remove(1));
        System.out.println(list);
        System.out.println(list.indexOf("中文"));
    }
}

[9, ay, cc, coleak, 中文]

true

cc

false

true

ay

[9, cc, 中文]

2

import java.util.ArrayList;
import java.util.Arrays;
public class Main {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>(Arrays.asList("aaa","bb","c"));
        list.add("aaa");
        list.add("aab");
        list.add("aaaa");
        list.removeIf(s ->s.length()!=3);
        System.out.println(list);
    }
}

[aaa, aaa, aab]

迭代器

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class Main {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("A", "B", "C");
        Iterator<String> var = list.iterator();
        while(var.hasNext()) {
            String s = (String)var.next();
            System.out.println(s);
        }
    }
    }

迭代器的使用是一次性的,用了之后就不能用了,如果需要再次进行遍历操作,那么需要重新生成一个迭代器对象

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class Main {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("A", "B", "C");
        list.forEach(System.out::println);
    }
    }
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class Main {
    public static void main(String[] args) {
        Test test=new Test();
        test.forEach(System.out::println);
    }
    public static class Test implements Iterable<String>{   
        //这里我们随便写一个类,让其实现Iterable接口
        @Override
        public Iterator<String> iterator() {
            return new Iterator<String>() {   
                //生成一个匿名的Iterator对象
                @Override
                public boolean hasNext() {   
                    //这里随便写的,直接返回true,这将会导致无限循环
                    return true;
                }
                @Override
                public String next() {   
                    //每次就直接返回一个字符串吧
                    return "coleak";
                }
            };
        }
    }
    }
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
public class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
        ListIterator<String> iterator = list.listIterator();
        iterator.next();   //此时得到A
        iterator.set("X");  //将A原本位置的上的元素设定为成新的
        System.out.println(list);
        iterator.remove();
        iterator.forEachRemaining(System.out::println);
    }
    }

[X, B, C]

B

C

Queue|Deque|PriorityQueue

public interface Queue<E> extends Collection<E> {
    //队列的添加操作,是在队尾进行插入(只不过List也是一样的,默认都是尾插)
      //如果插入失败,会直接抛出异常
    boolean add(E e);
    //同样是添加操作,但是插入失败不会抛出异常
    boolean offer(E e);
    //移除队首元素,但是如果队列已经为空,那么会抛出异常
    E remove();
       //同样是移除队首元素,但是如果队列为空,会返回null
    E poll();
    //仅获取队首元素,不进行出队操作,但是如果队列已经为空,那么会抛出异常
    E element();
    //同样是仅获取队首元素,但是如果队列为空,会返回null
    E peek();
}
import java.util.LinkedList;
import java.util.Queue;
public class Main {
    public static void main(String[] args) {
        Queue<String> queue = new LinkedList<>();   //当做队列使用,还是很方便的
        queue.offer("AAA");
        queue.offer("BBB");
        System.out.println(queue.poll());
        System.out.println(queue.poll());
    }
    }

可以直接将一个LinkedList当做一个队列来使用

//在双端队列中,所有的操作都有分别对应队首和队尾的
public interface Deque<E> extends Queue<E> {
    //在队首进行插入操作
    void addFirst(E e);
    //在队尾进行插入操作
    void addLast(E e);
      //不用多说了吧?
    boolean offerFirst(E e);
    boolean offerLast(E e);
    //在队首进行移除操作
    E removeFirst();
    //在队尾进行移除操作
    E removeLast();
    //不用多说了吧?
    E pollFirst();
    E pollLast();
    //获取队首元素
    E getFirst();
    //获取队尾元素
    E getLast();
        //不用多说了吧?
    E peekFirst();
    E peekLast();
    //从队列中删除第一个出现的指定元素
    boolean removeFirstOccurrence(Object o);
    //从队列中删除最后一个出现的指定元素
    boolean removeLastOccurrence(Object o);
    // *** 队列中继承下来的方法操作是一样的,这里就不列出了 ***
    ...
    // *** 栈相关操作已经帮助我们定义好了 ***
    //将元素推向栈顶
    void push(E e);
    //将元素从栈顶出栈
    E pop();
    // *** 集合类中继承的方法这里也不多种介绍了 ***
    ...
    //生成反向迭代器,这个迭代器也是单向的,但是是next方法是从后往前进行遍历的
    Iterator<E> descendingIterator();
}
import java.util.Deque;
import java.util.LinkedList;
public class Main {
    public static void main(String[] args) {
        Deque<String> deque = new LinkedList<>();
        deque.push("AAA");
        deque.push("BBB");
        System.out.println(deque.pop());
        System.out.println(deque.pop());
    }
    }
import java.util.PriorityQueue;
import java.util.Queue;
public class Main {
    public static void main(String[] args) {
        Queue<Integer> queue = new PriorityQueue<>();
        queue.offer(10);
        queue.offer(4);
        queue.offer(5);
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
    }
    }
import java.util.PriorityQueue;
import java.util.Queue;
public class Main {
    public static void main(String[] args) {
        Queue<Integer> queue = new PriorityQueue<>((a,b)->b-a);
        queue.offer(10);
        queue.offer(4);
        queue.offer(5);
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
    }
    }

4

5

10

10

5

4

Set集合

  • 不允许出现重复元素
  • 不支持随机访问(不允许通过下标访问)

HashSet

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class Main {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        System.out.println(set.add("AAA"));   //这里我们连续插入两个同样的字符串
        System.out.println(set.add("AAA"));
        System.out.println(set);   //可以看到,最后实际上只有一个成功插入了
        System.out.println(set.remove("AAA"));
        System.out.println(set);
        set.addAll(Arrays.asList("A", "0", "-", "+"));
        System.out.println(set);
    }
    }

true

false

[AAA]

true

[]

[0, A, +, -]

LinkedHashSet

维持插入集合的顺序需要使用LinkedHashSet

public static void main(String[] args) {
    Set<String> set = new LinkedHashSet<>();
    set.addAll(Arrays.asList("A", "0", "-", "+"));
    System.out.println(set);
}

[A, 0, -, +]

TreeSet

它会在元素插入时进行排序

import java.util.TreeSet;
public class Main {
    public static void main(String[] args) {
        TreeSet<Integer> set = new TreeSet<>((a,b)->b-a);
        set.add(1);
        set.add(3);
        set.add(2);
        System.out.println(set);
    }
    }

[3, 2, 1]

键盘读入

import java.util.Scanner;
public class test {
    public static void main(String[] args)
    {
        //演示接受用户的输入
        //步骤
        //Scanner类 表示 简单文本扫描器,在java.util 包
        //1. 引入/导入 Scanner类所在的包
        //2. 创建 Scanner 对象 , new 创建一个对象,体会
        //   myScanner 就是 Scanner类的对象
        Scanner myScanner = new Scanner(System.in);
        //3. 接收用户输入了, 使用 相关的方法
        System.out.println("请输入名字");
        //当程序执行到 next 方法时,会等待用户输入~~~
        String name = myScanner.next(); //接收用户输入字符串
        System.out.println("请输入年龄");
        int age = myScanner.nextInt(); //接收用户输入int
        System.out.println("请输入薪水");
        double sal = myScanner.nextDouble(); //接收用户输入double
        System.out.println("人的信息如下:");
        System.out.println("名字=" + name + " 年龄=" + age + " 薪水=" + sal);
    }
}

Map

HashMap

import java.util.HashMap;
import java.util.Map;
public class Main {
    public static void main(String[] args) {
        Map<Integer, String> map = new HashMap<>();
        map.put(1, "小明");   //使用put方法添加键值对,返回值我们会在后面讨论
        map.put(2, "小红");
        map.put(4, "coleak");
        System.out.println(map.get(2)); //使用get方法根据键获取对应的值
        map.remove(2);
        System.out.println(map);
        System.out.println(map.keySet());
        System.out.println(map.values());
    }
    }
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Map<Integer , String> map = new HashMap<>();
        map.put(0, "单走");
        map.replace(0, ">>>");   //直接替换为新的
        System.out.println(map);
    }
    }
public static void main(String[] args) {
    Map<Integer , String> map = new HashMap<>();
    map.put(0, "单走");
    map.replace(0, "巴卡", "玛卡");   //只有键和值都匹配时,才进行替换
    System.out.println(map);
}
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
public class Main {
    public static void main(String[] args) {
        Map<Integer, String> map = new HashMap<>();
        map.put(1, "A");
        map.put(2, "B");
        map.compute(3, (k, v) -> {   //compute会将指定Key的值进行重新计算,若Key不存在,v会返回null
            return v+"M";     //这里返回原来的value+M
        });
        map.computeIfPresent(3, (k, v) -> {   //当Key存在时存在则计算并赋予新的值
            return v+"M";     //这里返回原来的value+M
        });
        System.out.println(map);
    }
    }

{1=A, 2=B, 3=nullMM}

import java.util.*;
public class Main {
    public static void main(String[] args) {
        List<Student> students = Arrays.asList(
                new Student("yoni", "English", 80),
                new Student("yoni", "Chiness", 98),
                new Student("yoni", "Math", 95),
                new Student("taohai.wang", "English", 50),
                new Student("taohai.wang", "Chiness", 72),
                new Student("taohai.wang", "Math", 41),
                new Student("Seely", "English", 88),
                new Student("Seely", "Chiness", 89),
                new Student("Seely", "Math", 92)
        );
        Map<String, Integer> scoreMap = new HashMap<>();
  //merge方法可以对重复键的值进行特殊操作
        students.forEach(student -> scoreMap.merge(student.getName(), student.getScore(), Integer::sum));
        scoreMap.forEach((k, v) -> System.out.println("key:" + k + "总分" + "value:" + v));
    }
    static class Student {
        private final String name;
        private final String type;
        private final int score;
        public Student(String name, String type, int score) {
            this.name = name;
            this.type = type;
            this.score = score;
        }
        public String getName() {
            return name;
        }
        public int getScore() {
            return score;
        }
        public String getType() {
            return type;
        }
    }
    }

LinkedHashMap

如果需要维护顺序,我们同样可以使用LinkedHashMap,它的内部对插入顺序进行了维护

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
public class Main {
    public static void main(String[] args) {
        Map<String , String> map = new LinkedHashMap<>();
        map.put("0", "十七张");
        map.put("+", "牌");
        map.put("P", "你能秒我");
        System.out.println(map);
        System.out.println(map.keySet());
        System.out.println(map.values());
    }
    }

{0=十七张, +=牌, P=你能秒我}

[0, +, P]

[十七张, 牌, 你能秒我]

Stream流

stream()

import java.util.*;
import java.util.stream.Collectors;
public class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("A");
        list.add("B");
        list.add("C");
        //Stream操作
        list = list     //链式调用
                .stream()    //获取流
                .filter(e -> !e.equals("B"))   //只允许所有不是B的元素通过流水线
                .collect(Collectors.toList());   //将流水线中的元素重新收集起来,变回List
        System.out.println(list);
    }
    }
import java.util.*;
import java.util.stream.Collectors;
public class Main {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(3);
        System.out.println(list);
        list = list
                .stream()
                .distinct()   //去重(使用equals判断)
                .sorted((a, b) -> b - a)    //进行倒序排列
                .map(e -> e+10)    //每个元素都要执行+1操作
                .limit(2)    //只放行前两个元素
                .collect(Collectors.toList());
        System.out.println(list);
    }
    }

[1, 2, 3, 3]

[13, 12]

stream会先记录每一步操作,而不是直接开始执行内容,当整个链式调用完成后,才会依次进行

ints()

import java.util.Random;
public class Main {
    public static void main(String[] args) {
        Random random = new Random();
        random
                .ints(-100, 100)   //生成-100~100之间的,随机int型数字(本质上是一个IntStream)
                .limit(10)   //只获取前10个数字(这是一个无限制的流,如果不加以限制,将会无限进行下去!)
                .filter(i -> i < 0)   //只保留小于0的数字
                .sorted()    //默认从小到大排序
                .forEach(System.out::println);   //依次打印
    }
    }
import java.util.IntSummaryStatistics;
import java.util.Random;
public class Main {
    public static void main(String[] args) {
        Random random = new Random();  //Random是一个随机数工具类
        IntSummaryStatistics statistics = random
                .ints(0, 100)
                .limit(1000)
                .summaryStatistics();    //获取语法统计实例
        System.out.println(statistics.getMax());  //快速获取最大值
        System.out.println(statistics.getCount());  //获取数量
        System.out.println(statistics.getAverage());   //获取平均值
    }
    }
import java.util.*;
import java.util.stream.Collectors;
public class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("A,B");
        list.add("C,D");
        list.add("E,F");   //我们想让每一个元素通过,进行分割,变成独立的6个元素
        list = list
                .stream()    //生成流
                .flatMap(e -> Arrays.stream(e.split(",")))    //分割字符串并生成新的流
                .collect(Collectors.toList());   //汇成新的List
        System.out.println(list);   //得到结果
    }
    }

[A, B, C, D, E, F]

Collections工具类

import java.util.*;
import java.util.stream.Collectors;
public class Main {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(2, 3, 8, 9, 10, 13);
        System.out.println(Collections.binarySearch(list, 8));
        System.out.println(Collections.max(list));
        Collections.fill(list, 6);
        System.out.println(list);
        List<Integer> list2 = new ArrayList<>(Arrays.asList(1,2,3,4,5));
        System.out.println(Collections.indexOfSubList(list2, Arrays.asList(4, 5)));
    }
    }

2

13

[6, 6, 6, 6, 6, 6]

3

目录
相关文章
|
9天前
|
存储 缓存 安全
Java 集合江湖:底层数据结构的大揭秘!
小米是一位热爱技术分享的程序员,本文详细解析了Java面试中常见的List、Set、Map的区别。不仅介绍了它们的基本特性和实现类,还深入探讨了各自的使用场景和面试技巧,帮助读者更好地理解和应对相关问题。
30 5
|
21天前
|
存储 缓存 安全
Java 集合框架优化:从基础到高级应用
《Java集合框架优化:从基础到高级应用》深入解析Java集合框架的核心原理与优化技巧,涵盖列表、集合、映射等常用数据结构,结合实际案例,指导开发者高效使用和优化Java集合。
33 4
|
27天前
|
存储 缓存 安全
java 中操作字符串都有哪些类,它们之间有什么区别
Java中操作字符串的类主要有String、StringBuilder和StringBuffer。String是不可变的,每次操作都会生成新对象;StringBuilder和StringBuffer都是可变的,但StringBuilder是非线程安全的,而StringBuffer是线程安全的,因此性能略低。
44 8
|
27天前
|
Java 开发者
在 Java 中,一个类可以实现多个接口吗?
这是 Java 面向对象编程的一个重要特性,它提供了极大的灵活性和扩展性。
60 1
|
1月前
|
存储 安全 Java
java.util的Collections类
Collections 类位于 java.util 包下,提供了许多有用的对象和方法,来简化java中集合的创建、处理和多线程管理。掌握此类将非常有助于提升开发效率和维护代码的简洁性,同时对于程序的稳定性和安全性有大有帮助。
63 17
|
1月前
|
Java
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
30 2
|
1月前
|
存储 Java
判断一个元素是否在 Java 中的 Set 集合中
【10月更文挑战第30天】使用`contains()`方法可以方便快捷地判断一个元素是否在Java中的`Set`集合中,但对于自定义对象,需要注意重写`equals()`方法以确保正确的判断结果,同时根据具体的性能需求选择合适的`Set`实现类。
|
1月前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
1月前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
116 4
|
1月前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
60 2
下一篇
DataWorks