【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

coleak
+关注
目录
打赏
0
0
0
0
47
分享
相关文章
|
10天前
|
重学Java基础篇—Java类加载顺序深度解析
本文全面解析Java类的生命周期与加载顺序,涵盖从加载到卸载的七个阶段,并深入探讨初始化阶段的执行规则。通过单类、继承体系的实例分析,明确静态与实例初始化的顺序。同时,列举六种触发初始化的场景及特殊场景处理(如接口初始化)。提供类加载完整流程图与记忆口诀,助于理解复杂初始化逻辑。此外,针对空指针异常等问题提出排查方案,并给出最佳实践建议,帮助开发者优化程序设计、定位BUG及理解框架机制。最后扩展讲解类加载器层次与双亲委派机制,为深入研究奠定基础。
32 0
Java 集合框架中的老炮与新秀:HashTable 和 HashMap 谁更胜一筹?
嗨,大家好,我是技术伙伴小米。今天通过讲故事的方式,详细介绍 Java 中 HashMap 和 HashTable 的区别。从版本、线程安全、null 值支持、性能及迭代器行为等方面对比,帮助你轻松应对面试中的经典问题。HashMap 更高效灵活,适合单线程或需手动处理线程安全的场景;HashTable 较古老,线程安全但性能不佳。现代项目推荐使用 ConcurrentHashMap。关注我的公众号“软件求生”,获取更多技术干货!
66 3
|
16天前
|
《从头开始学java,一天一个知识点》之:输入与输出:Scanner与System类
你是否也经历过这些崩溃瞬间?三天教程连`i++`和`++i`都说不清,面试时`a==b`与`equals()`区别大脑空白,代码总是莫名报NPE。这个系列就是为你打造的Java「速效救心丸」!每天1分钟,地铁通勤、午休间隙即可学习。直击高频考点和实际开发中的“坑位”,拒绝冗长概念,每篇都有可运行代码示例。涵盖输入输出基础、猜数字游戏、企业编码规范、性能优化技巧、隐藏技能等。助你快速掌握Java核心知识,提升编程能力。点赞、收藏、转发,助力更多小伙伴一起成长!
42 19
重学Java基础篇—类的生命周期深度解析
本文全面解析了Java类的生命周期,涵盖加载、验证、准备、解析、初始化、使用及卸载七个关键阶段。通过分阶段执行机制详解(如加载阶段的触发条件与技术实现),结合方法调用机制、内存回收保护等使用阶段特性,以及卸载条件和特殊场景处理,帮助开发者深入理解JVM运作原理。同时,文章探讨了性能优化建议、典型异常处理及新一代JVM特性(如元空间与模块化系统)。总结中强调安全优先、延迟加载与动态扩展的设计思想,并提供开发建议与进阶方向,助力解决性能调优、内存泄漏排查及框架设计等问题。
29 5
|
17天前
|
《从头开始学java,一天一个知识点》之:字符串处理:String类的核心API
🌱 **《字符串处理:String类的核心API》一分钟速通!** 本文快速介绍Java中String类的3个高频API:`substring`、`indexOf`和`split`,并通过代码示例展示其用法。重点提示:`substring`的结束索引不包含该位置,`split`支持正则表达式。进一步探讨了String不可变性的高效设计原理及企业级编码规范,如避免使用`new String()`、拼接时使用`StringBuilder`等。最后通过互动解密游戏帮助读者巩固知识。 (上一篇:《多维数组与常见操作》 | 下一篇预告:《输入与输出:Scanner与System类》)
45 11
|
10天前
|
重学Java基础篇—Java Object类常用方法深度解析
Java中,Object类作为所有类的超类,提供了多个核心方法以支持对象的基本行为。其中,`toString()`用于对象的字符串表示,重写时应包含关键信息;`equals()`与`hashCode()`需成对重写,确保对象等价判断的一致性;`getClass()`用于运行时类型识别;`clone()`实现对象复制,需区分浅拷贝与深拷贝;`wait()/notify()`支持线程协作。此外,`finalize()`已过时,建议使用更安全的资源管理方式。合理运用这些方法,并遵循最佳实践,可提升代码质量与健壮性。
21 1
|
23天前
|
课时14:Java数据类型划分(初见String类)
课时14介绍Java数据类型,重点初见String类。通过三个范例讲解:观察String型变量、&quot;+&quot;操作符的使用问题及转义字符的应用。String不是基本数据类型而是引用类型,但使用方式类似基本类型。课程涵盖字符串连接、数学运算与字符串混合使用时的注意事项以及常用转义字符的用法。
课时11:综合实战:简单Java类
本次分享的主题是综合实战:简单 Java 类。主要分为两个部分: 1.简单 Java 类的含义 2.简单 Java 类的开发
|
24天前
|
Java代码结构解析:类、方法、主函数(1分钟解剖室)
### Java代码结构简介 掌握Java代码结构如同拥有程序世界的建筑蓝图,类、方法和主函数构成“黄金三角”。类是独立的容器,承载成员变量和方法;方法实现特定功能,参数控制输入环境;主函数是程序入口。常见错误包括类名与文件名不匹配、忘记static修饰符和花括号未闭合。通过实战案例学习电商系统、游戏角色控制和物联网设备监控,理解类的作用、方法类型和主函数任务,避免典型错误,逐步提升编程能力。 **脑图速记法**:类如太空站,方法即舱段;main是发射台,static不能换;文件名对仗,括号要成双;参数是坐标,void不返航。
45 5
课时37:综合实战:数据表与简单Java类映射转换
今天我分享的是数据表与简单 Java 类映射转换,主要分为以下四部分。 1. 映射关系基础 2. 映射步骤方法 3. 项目对象配置 4. 数据获取与调试