Java集合操作

简介: java.utilListCollection下有两个数据结构,一个是ArrayList,一个是LinkedList。

java.util

List

Collection下有两个数据结构,一个是ArrayList,一个是LinkedList。


其中ArrayList的底层是Object[]数组,优势在于可以随机访问get。

而LinkedList的底层是链表,访问某个元素的效率比ArrayList低,因为需要移动指针,但优势在于需要大量增删改的时候速度很快。

在选择上,如果要进行大量的增删操作,建议LinkedList。如果要进行大量的改查操作,建议ArrayList。

LinekedList

常用方法:


add()添加元素到链表尾部

addFirst()添加元素到链表头部

addLast()添加元素到链表尾部

get(int index) 获取第index个元素

remove(int index)删除第index个元素

size()返回链表的长度

clear()清空链表

ArrayList

==优点:==访问单个元素特别快,因此多用于改查操作。

==缺点:==比如删除,插入这种动作需要大部分元素移动,不适用于大数据量的操作。

构造方法


//不推荐
   ArrayList<Integer> n = new ArrayList<>();
//推荐用接口代替具体实现类
   List<Integer> list0 = new ArrayList<>();

add() 添加元素


set(int index,E e) 把第index个元素修改为e


get(int index)获取第index个元素


size() 方法


addAll(Collection<> c) 将另一个Collection集合的元素全部添加进来


indexOf(Object o) 返回元素 o 的下标


实例

    List<Integer> list0 = new ArrayList<>();
    List<Integer> list1 = new ArrayList<>();
        list1.add(2);
        list1.add(3);
        list0.add(1);
        list0.add(0,2);//被插入的位置及后面所有元素都向后移动一个单位
        System.out.println("list0的大小是"+ list0.size()+"  list0的内容为:"+ list0.toString());
        System.out.println("list1的大小是"+ list0.size()+"  list1的内容为:"+ list0.toString());
        System.out.println("修改list0的第一个位置为 0 ");
        list0.set(0,0);
        System.out.println(list0.toString());
        System.out.println("把list1中所有元素移动到list0中,效果为:");
        list0.addAll(list1);
        System.out.println(list0.toString());

运行结果:


image.png


遍历方式

遍历和遍历数组一致,无非数组长度的表示不同


toString() 已经写好直接用


System.out.println(list0.toString());


for循环


for(int i=0;i<list0.size();i++){
    System.out.print(list0.get(i)+" ");
}

加强for循环


注意:加强for循环的数据类型应该为包装类


for(Integer element:list0){
     System.out.print(num);
}


迭代器


ArrayList<Integer> link = ArrayList<>();
Iterator<Integer> iterator = link.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

运行结果:


image.png


Set

Set集合也可以当作数组来用,不过Set集合中不允许存储重复的元素,因此经常使用Set集合去重。

HashSet按Hash算法来存储集合中的元素,因此具有很好的存取和查找性能。底层数据结构是哈希表;

TreeSet底层是红黑树,TreeSet可以确保集合元素处于排序状态。

需要注意的是:


HashSet并不具备自动排序的功能,但是有些时候放进HashSet中的元素也会有顺序,然而这只是一种巧合,如果放进去的元素很多,HashSet并不能保证其顺序。


TreeSet具备自动排序的功能,将Integer或者Double放进TreeSet会自动帮我们排序,但是如果我们想将对象放进TreeSet,必须要让对象的类继承Comparable接口,并重写compareTo方法,使其具备比较大小的能力,这样TreeSet才知道按什么顺序存储对象。


Set中放入对象时需要重写equals方法来定义如何判断两个元素是否相同,其实Set的知识点还是很多的,本文主要面向参加蓝桥杯的同学,所以也不用过于深究,这里只介绍Set的简单使用~


HahSet

优点:


存取和查找性能特别好

缺点:


不能自动排序

与List中不同的方法已加粗


构造方法 依然推荐下面这种 通过接口来代替实例对象的方法


HashSet<Double> set = new HashSet<>();


Set<Double> set = new HashSet<>();


add() 添加元素


size() 方法


addAll(Collection<> c) 将另一个Collection集合的元素全部添加进来


remove(int index) 删除下标为index 的元素


contains(Object o) 判断是否含有该元素


contains(Collection c) 判断是否含有该集合中的元素(因为在Set集合中,所有元素不允许重复)


isEmpt() 判断集合是否为空


clear() 清空集合中所有元素


运行结果:


image.png


TreeSet

优点:


自动排序

可以存储对象,不局限于是Object下那几种数据类型

缺点:


如果想让TreeSet存储对象,需要继承Compareable接口并重写compareTo方法。

构造方法 同上 推荐下面这种


TreeSet<Double> set = new TreeSet<>();


Set<Double> set = new TreeSet<>();


其余方法和HashSet一致


遍历方式

toString() 已经写好了直接用就行了


加强for循环


注意:加强for循环的数据类型应该为包装类,即Integer、Double这种。


**迭代器 ** 这是List和HashSet所没有的


注意:迭代器不是new出来的,而是和Set接口创建HashSet一样,通过Iterator接口来代替对象实例化。

Iterator<Integer> iterator = set0.iterator();
  while(iterator.hasNext()){
        int temp = iterator.next();
        System.out.print(temp+" ");
    }

运行结果:

image.png


Map

List与Set中的元素都是单个存储的,而Map中的元素是成对存储的,每个元素由键与值两部分组成,通过键可以找对所对应的值。

Map接口中最常用的实现类是HashMap,存储数据采用的哈希表结构,元素的存取顺序不能保证一致。

需要注意的是,Map中的集合不能包含重复的键,值可以重复;每个键只能对应一个值.

HashMap类

构造方法 同样,推荐第一种构造方式


HashMap<String,Integer> map = new HashMap<>();


Map<String, Integer> map = new HashMap<>();


put(<>key,<>val) 存放数据


get(Key key) 通过键得到键值


contains() 判断是否包含该键或值


containsKey(key) 判断是否包含该键


containsValue(val) 判断是否包含该值


replace(key ,val) 修改键对应的值


remove(key) 删除指定元素


keySet() 返回map所有键的Set集合


values() 返回map所有值的Collection集合


Set<<Map.Entry<k,v> entrySet() 返回map所有**键值对的Set集合**


很重要这个


Map.Entry<K,V>

是一个接口,**Map.entrySet()**方法返回地图的集合视图,其元素属于此类。


getKey() 获取键

getValue() 获取值

遍历方式

toString()


加强for循环


模糊版

System.out.println("输出所有人的名字: (键)");
        for (String name:map.keySet()){
            System.out.println(name);
        }
        System.out.println("输出所有年龄:(值)");
        for (Integer age:map.values()){
            System.out.println(age);
        }

清晰版

Set<String> names:map.keySet();
for (int name:names) {
            System.out.println(name);
    }
Set<Integer> ages:map.values();
for (int age:ages) {
            System.out.println(age);
    }


entrySet() 拿到map的键和值的集合再遍历


T1.0 头大版本 通过接口来代替实例对象

HashMap<Integer,Integer> map = new HashMap();
//得到map的所有键的Set集合
Set<Map.Entry<Integer,Integer>> entrySet = map.entrySet();
//加强for循环遍历每一个键
for (Map.Entry<Character,Integer>entry:entrySet){
    int value = entry.getValue();
    char key = entry.getKey();
}


清爽版

for (Map.Entry<String, Integer> entry : map.entrySet()) {
        System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());
    }


迭代器

//为map的键的设置迭代器 输出所有名字
        Iterator<String> iterator = map.keySet().iterator();
        while (iterator.hasNext()){
            String name = iterator.next();
            System.out.print(name+" ");
        }
        System.out.println();
        //用迭代器输出所有键对应的值
        Iterator<Integer> iterator1 = map.values().iterator();
        while (iterator1.hasNext()){
            int age = iterator1.next();
            System.out.print(age+"  ");
        }

运行结果:

image.png

常用模型 - 记录某类型值出现的次数


实际案例

package Cup.API;
import java.util.HashMap;
import java.util.Map;
//统计每个数字出现的次数
public class Test {
    public static void main(String[] args) {
        int[] arr = {5,5,2,2,5,7,4,2,9,8,1,2,3,5,4,7,8,9,6};
        Map<Integer,Integer> map = new HashMap<>();
        for (int i : arr) {
            if (!map.containsKey(i)) {
                map.put(i, 1);
            } else {
                int count = map.get(i);
                map.replace(i, ++count);
            }
        }
        //输出所有键各自对应的值
        //用Map.Entry获取键值对
       for (Map.Entry<Integer,Integer> entry: map.entrySet()){
               System.out.println(entry.getKey()+"出现的次数为"+entry.getValue());
       }
    }
}

运行结果:


image.pngimage.pngimage.png


image.png

相关文章
|
2月前
|
Java 大数据 API
Java Stream API:现代集合处理与函数式编程
Java Stream API:现代集合处理与函数式编程
231 100
|
2月前
|
Java API 数据处理
Java Stream API:现代集合处理新方式
Java Stream API:现代集合处理新方式
262 101
|
2月前
|
算法 Java
50道java集合面试题
50道 java 集合面试题
|
1月前
|
存储 算法 安全
Java集合框架:理解类型多样性与限制
总之,在 Java 题材中正确地应对多样化与约束条件要求开发人员深入理解面向对象原则、范式编程思想以及JVM工作机理等核心知识点。通过精心设计与周密规划能够有效地利用 Java 高级特征打造出既健壮又灵活易维护系统软件产品。
70 7
|
4月前
|
Oracle Java 关系型数据库
掌握Java Stream API:高效集合处理的利器
掌握Java Stream API:高效集合处理的利器
384 80
|
4月前
|
安全 Java API
Java 8 Stream API:高效集合处理的利器
Java 8 Stream API:高效集合处理的利器
284 83
|
2月前
|
存储 Java Go
对比Java学习Go——函数、集合和OOP
Go语言的函数支持声明与调用,具备多返回值、命名返回值等特性,结合`func`关键字与类型后置语法,使函数定义简洁直观。函数可作为一等公民传递、赋值或作为参数,支持匿名函数与闭包。Go通过组合与接口实现面向对象编程,结构体定义数据,方法定义行为,接口实现多态,体现了Go语言的简洁与高效设计。
|
3月前
|
存储 缓存 安全
Java集合框架(二):Set接口与哈希表原理
本文深入解析Java中Set集合的工作原理及其实现机制,涵盖HashSet、LinkedHashSet和TreeSet三大实现类。从Set接口的特性出发,对比List理解去重机制,并详解哈希表原理、hashCode与equals方法的作用。进一步剖析HashSet的底层HashMap实现、LinkedHashSet的双向链表维护顺序特性,以及TreeSet基于红黑树的排序功能。文章还包含性能对比、自定义对象去重、集合运算实战和线程安全方案,帮助读者全面掌握Set的应用与选择策略。
244 23
|
3月前
|
存储 缓存 安全
Java集合框架(三):Map体系与ConcurrentHashMap
本文深入解析Java中Map接口体系及其实现类,包括HashMap、ConcurrentHashMap等的工作原理与线程安全机制。内容涵盖哈希冲突解决、扩容策略、并发优化,以及不同Map实现的适用场景,助你掌握高并发编程核心技巧。
|
3月前
|
安全 Java 开发者
Java集合框架:详解Deque接口的栈操作方法全集
理解和掌握这些方法对于实现像浏览器后退功能这样的栈操作来说至关重要,它们能够帮助开发者编写既高效又稳定的应用程序。此外,在多线程环境中想保证线程安全,可以考虑使用ConcurrentLinkedDeque,它是Deque的线程安全版本,尽管它并未直接实现栈操作的方法,但是Deque的接口方法可以相对应地使用。
231 12