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

相关文章
Java 集合框架中的老炮与新秀:HashTable 和 HashMap 谁更胜一筹?
嗨,大家好,我是技术伙伴小米。今天通过讲故事的方式,详细介绍 Java 中 HashMap 和 HashTable 的区别。从版本、线程安全、null 值支持、性能及迭代器行为等方面对比,帮助你轻松应对面试中的经典问题。HashMap 更高效灵活,适合单线程或需手动处理线程安全的场景;HashTable 较古老,线程安全但性能不佳。现代项目推荐使用 ConcurrentHashMap。关注我的公众号“软件求生”,获取更多技术干货!
66 3
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。HashSet基于哈希表实现,提供高效的元素操作;TreeSet则通过红黑树实现元素的自然排序,适合需要有序访问的场景。本文通过示例代码详细介绍了两者的特性和应用场景。
86 6
|
5月前
|
深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。
【10月更文挑战第16天】本文深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。HashSet基于哈希表实现,添加元素时根据哈希值分布,遍历时顺序不可预测;而TreeSet利用红黑树结构,按自然顺序或自定义顺序存储元素,确保遍历时有序输出。文章还提供了示例代码,帮助读者更好地理解这两种集合类型的使用场景和内部机制。
70 3
Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位
【10月更文挑战第16天】Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位。本文通过快速去重和高效查找两个案例,展示了Set如何简化数据处理流程,提升代码效率。使用HashSet可轻松实现数据去重,而contains方法则提供了快速查找的功能,彰显了Set在处理大量数据时的优势。
65 2
java常见的集合类有哪些
Map接口和Collection接口是所有集合框架的父接口: 1. Collection接口的子接口包括:Set接口和List接口 2. Map接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及 Properties等 3. Set接口的实现类主要有:HashSet、TreeSet、LinkedHashSet等 4. List接口的实现类主要有:ArrayList、LinkedList、Stack以及Vector等
Java 集合江湖:底层数据结构的大揭秘!
小米是一位热爱技术分享的程序员,本文详细解析了Java面试中常见的List、Set、Map的区别。不仅介绍了它们的基本特性和实现类,还深入探讨了各自的使用场景和面试技巧,帮助读者更好地理解和应对相关问题。
79 5
Java 集合框架优化:从基础到高级应用
《Java集合框架优化:从基础到高级应用》深入解析Java集合框架的核心原理与优化技巧,涵盖列表、集合、映射等常用数据结构,结合实际案例,指导开发者高效使用和优化Java集合。
89 4
在 Java 中,如何遍历一个 Set 集合?
【10月更文挑战第30天】开发者可以根据具体的需求和代码风格选择合适的遍历方式。增强for循环简洁直观,适用于大多数简单的遍历场景;迭代器则更加灵活,可在遍历过程中进行更多复杂的操作;而Lambda表达式和`forEach`方法则提供了一种更简洁的函数式编程风格的遍历方式。
判断一个元素是否在 Java 中的 Set 集合中
【10月更文挑战第30天】使用`contains()`方法可以方便快捷地判断一个元素是否在Java中的`Set`集合中,但对于自定义对象,需要注意重写`equals()`方法以确保正确的判断结果,同时根据具体的性能需求选择合适的`Set`实现类。
|
4月前
|
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
73 2
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等