首页 > 编程语言 >Java学习Day07——集合

Java学习Day07——集合

时间:2024-12-11 18:57:41浏览次数:5  
标签:set Java Day07 System println add 集合 public out

1.  集合与数组

1.1  数组的缺陷

1.  长度开始时必须指定,而且一旦指定,不能更改
2.  保存的必须为同一类型的元素
3.  使用数组进行增加/删除元素的示意代码-比较麻烦

 1.2  集合

1.  可以动态保存任意多个对象,使用比较方便

2.  提供了一系列方便的操作对象的方法:add、remove、set、get等

3.  使用集合添加,删除新元素的示意代码-简洁明了

 2.  集合的框架体系

根据不同的数据结构,比如数组,线性,链表结构等开发出不同的类。

这些类称为java中集合框架。

Java 的集合类很多,主要分为两大类,如图 : 

 

 2.1  Vector类

public class Vector<E>  ---<E>理解为Object
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable
Vector类实现了可扩展的对象数组。 像数组一样,它包含可以使用下标访问的元素。 但是, Vector的大小可以根据需要增长或缩小,以适应在创建Vector之后添加和删除项目。 
-----------------我们如果想使用Vector类,那么必须创建Vector类对象------------
Vector() 
构造一个空向量,使其内部数据数组的大小为 10 ,标准容量增量为零。

Vector(int initialCapacity) 
构造具有指定初始容量并且其容量增量等于零的空向量。 

import java.util.Vector;

public class Test02 {
    public static void main(String[] args) {
        //1.创建一个Vector对象
//        Vector v=new Vector();//默认容量为10
        Vector v=new Vector(3);
        //2. 添加元素
        v.add("张三");
        v.add("李四");
        v.add(1,"王五");//插入
        v.add("张三");//插入---允许元素重复

        //3.获取元素的个数
        System.out.println("元素的个数:"+v.size());

        //4. 获取指定位置的元素
        System.out.println("获取第一个位置的元素:"+v.get(1));

        //5.判断某个元素是否存在.
        System.out.println("张三2是否存在:"+v.contains("张三2"));

        //6.查找元素第一次在Vector中出现的位置。
        System.out.println("张三2第一次出现的位置:"+v.indexOf("张三2"));

        System.out.println("修改前:"+v);
        //7.修改指定位置元素
        v.set(1,"赵六");
        System.out.println("修改后:"+v);

        //8.删除
        v.remove(1);//删除指定位置的元素
        System.out.println("删除后:"+v);
        //9.清空
        v.clear();
        System.out.println("清空后:"+v);
    }
}

Vector集合的遍历

Vector v=new Vector(3);
        //2. 添加元素
        v.add("张三");
        v.add("");
        v.add(1,"王五");//插入
        v.add("张三");//插入---允许元素重复

        //for循环
        for(int i=0;i<v.size();i++){
            System.out.println(v.get(i));
        }
        //增强for循环遍历
        System.out.println("=============增强for循环遍历=============");
        for(Object o:v){
            System.out.println(o);
        }
        //迭代器遍历
        System.out.println("===============迭代器遍历===================");
        Iterator iterator = v.iterator();//获取v的迭代器对象
        while (iterator.hasNext()){ //判断是否还有元素
            Object o = iterator.next();//获取元素并移动指针
            System.out.println(o);
        }

2.2   ArrayList集合

 public class ArrayList<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable
可调整大小的数组的实现List接口。 实现所有可选列表操作,并允许所有元素,包括null 。 除了实现List 接口之外,该类还提供了一些方法来操纵内部使用的存储列表的数组的大小。 (这个类是大致相当于Vector,不同之处在于它是不同步的)。 

Vector和ArrayList的区别?
Vector:底层使用的还是数组,同步操作,线程安全的。效率慢。
ArrayList:底层使用还是数组,非同步操作,线程不安全。效率高。---【一般使用】

------------------如果我们想使用ArrayList必须创建该类对象-------------------
ArrayList() 
构造一个初始容量为十的空列表。 
ArrayList(int initialCapacity) 
构造具有指定初始容量的空列表。

public static void main(String[] args) {
        ArrayList list=new ArrayList();//创建一个集合对象
        ArrayList list2=new ArrayList();//创建一个集合对象
        list2.add("java01");
        list2.add("java02");
        list2.add("java03");
        list2.add("java06");
        list2.add("java02");

        list.addAll(list2);//把list2集合中的内容放到list集合中

        System.out.println("集合中的内容:"+list);

        Object clone = list.clone(); //克隆方法

        System.out.println("集合是否为空:"+list.isEmpty());

        List list1 = list.subList(1, 3);//截取集合
        System.out.println(list1);

        Object[] objects = list.toArray();
        System.out.println(Arrays.toString(objects));
    }

 ArrayList底层源码

1. 构造函数
 public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            //Object[] elementData;
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
}
2.add方法。
    public boolean add(Object e) { //E:理解为Object
        ensureCapacityInternal(size + 1);  // 扩容数组
        elementData[size++] = e;//把元素赋值给指定下的位置
        return true;
    }
  private void ensureExplicitCapacity(int minCapacity) {//元素的个数
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length; //求原来数组的长度
        int newCapacity = oldCapacity + (oldCapacity >> 1);// >>1表示0.5倍--1.5
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0) //1555555555555555 
            newCapacity = hugeCapacity(minCapacity);
        // 数组的赋值和扩容
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
3.size方法.
      public int size() {
        return size;
    }
4.get方法 get(2)
    public E get(int index) {

        rangeCheck(index); //检查下标是否合法

        return elementData(index);
    }
    private void rangeCheck(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
5.remove(1)删除方法:
    public E remove(int index) {
        rangeCheck(index); //检查下标是否合法
        modCount++;
        E oldValue = elementData(index); //获取该位置上的元素
        //5-2-1
        int numMoved = size - index - 1; //size元素的个数 index删除的位置 
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }

------------------------------------------------------------------------
ArrayList查询效率高,删除操作设计到位移时比较慢。

 2.3  LinkedList集合

 LinkedList的使用

public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, Serializable
双向链表实现了List和Deque接口。 实现所有可选列表操作,并允许重复元素(包括null )。 

 LinkedList() 
构造一个空列表。
无需指定初始化容器,因为他底层不是用的数组结构。

import java.util.Iterator;
import java.util.LinkedList;

public class Test01 {
    public static void main(String[] args) {
        LinkedList list=new LinkedList();
        //添加元素--->add和addLast是两个人写的。
        list.add("java01");
        list.add("java02");
        list.addFirst("java03");
        list.addLast("java04");
        //修改
        list.set(1,"java05");
        System.out.println(list);
        //长度
        System.out.println(list.size());
        //获取指定位置的元素
        System.out.println(list.get(2));
        //截取
        System.out.println(list.subList(1, 3));
        //判断是否包含某元素
        System.out.println(list.contains("java05"));

        //第一次出现的位置
        System.out.println(list.indexOf("java05"));
        //遍历
        System.out.println("==================================");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        System.out.println("==================================");
        for (Object o:list){
            System.out.println(o);
        }
        System.out.println("==================================");
        Iterator iterator=list.iterator();
        while (iterator.hasNext()){
            Object o=iterator.next();
            System.out.println(o);
        }
        System.out.println("==================================");
        list.forEach(item->System.out.println(item));
        //删除
    }
}

LinkedList底层实现原理

构造方法:
    transient int size = 0;
    transient Node<E> first=null;
    transient Node<E> last=null;
    public LinkedList() {
    }
add()添加方法
     public boolean add(E e) {
        linkLast(e);
        return true;
    }
    void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }
    private static class Node<E> {
        E item; //表示当前添加的元素
        Node<E> next; //表示下一个node节点
        Node<E> prev; //表示上一个node接口

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

get(2): 获取指定元素. ---要么从链表的头 要么从链表的尾  直到索引得到位置。  
    public E get(int index) {
        checkElementIndex(index);//检查下标是否合法
        return node(index).item;
    }

    //index=1   size=5  
    Node<E> node(int index) {
        if (index < (size >> 1)) { //5/2=
            Node<E> x = first; //
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node<E> x = last;     
            for (int i = size - 1; i > index; i--){
                x = x.prev;
            }
            return x;
        }
    }

remove(2):移除元素
    public E remove(int index) {
        checkElementIndex(index);
        return unlink(node(index)); //node(index):找到被移除的节点对象
    }
   E unlink(Node<E> x) {
        // assert x != null;
        final E element = x.item;
        final Node<E> next = x.next; //java04节点
        final Node<E> prev = x.prev; //java02节点

        if (prev == null) {
            first = next;
        } else {
            prev.next = next; //java02指向java04节点
            x.prev = null; //java03节点的上一个置空
        }

        if (next == null) {
            last = prev;
        } else {
            next.prev = prev; //java04的指向java02
            x.next = null; //java03节点的下一个置空
        }

        x.item = null; //item=null;
        size--; //数量减一
        modCount++;
        return element; //java03内容
    }

2.4  HasSet

实现了Set,该类不允许重复,而且无序 且没有下标。底层使用hash算法实现。 HashSet元素是否重复根据哈希值以及equals方法判断。

import java.util.HashSet;
import java.util.Iterator;

public class Test01 {
    public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();

        //添加元素
        set.add("java01");
        set.add("java06");
        set.add("java02");
        set.add("java08");
        set.add("java06");
        set.add(null);
        set.add(null);
        set.add(null);
        System.out.println(set); //set不允许重复而且无序,允许存放null.

        //元素的个数
        System.out.println(set.size());
        //遍历--增强
        for (String s : set) {
            System.out.println(s);
        }
        System.out.println("==========================");
        Iterator<String> iterator = set.iterator();
        while (iterator.hasNext()) {
            String s = iterator.next();
            System.out.println(s);
        }
        System.out.println("==========================");
        set.forEach(item->System.out.println(item));//jdk1.8

        //删除
        boolean b = set.remove("java06");
        System.out.println(set);
        //清空
//        set.clear();
       //包含某个元素
        System.out.println(set.contains("java02"));
    }
}
import java.util.HashSet;
import java.util.Objects;

public class Test02 {
    public static void main(String[] args) {
        People p1 = new People("jack", 23);
        People p2 = new People("tom", 33);
        People p4 = new People("jack", 33);
        People p3 = new People("smith", 23);
        HashSet<People> set=new HashSet<>();
        set.add(p1);
        set.add(p2);
        set.add(p3);
        set.add(p4); //判断重复的依据: hashCode()和equals()比较的地址. 先比较hashCode(),如果hashcode值相同再比较equals()。 如果hashcode值不同则不会调用equals();
        System.out.println("集合元素的个数:"+set.size());
        System.out.println(set);
    }
}
class People{
    private String name;
    private int age;

    public People(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        People people = (People) o;
        return this.getAge() == people.getAge() && Objects.equals(getName(), people.getName());
    }


    @Override
    public int hashCode() { //"aaa"--->整数    
        return Objects.hash(getName(), getAge()); //根据名称和年龄计算hash值。
    }

    @Override
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                ", 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;
    }
}

 如果集合HahSet中添加的类型为自定义类对象。那么该类建议重写equals和hashcode方法。

 2.5  HashMap

它底层也是使用了Hash表。 存放的元素key---value键值对元素。而且它的key不允许重复。但是value允许重复。 而且HashMap运行key和value为null;

基于哈希表的实现的Map接口。 此实现提供了所有可选的地图操作,并允许null的值和null键。

import java.util.HashMap;
import java.util.Set;

public class Test04 {
    public static void main(String[] args) {
        HashMap map=new HashMap();//map的键是唯一的,如果添加相同的键,后面的值会覆盖前面的值。
        //添加元素
        map.put("name","郭宇轩");//添加元素到map对象中
        map.put("age",16);
        map.put("sex","男");
        map.put("name","刘力元");
        System.out.println(map);

        //获取元素--通过key获取元素的value值
        System.out.println(map.get("name"));
        //元素的个数
        System.out.println("元素的个数:"+map.size());
        //删除元素
        map.remove("sex");
        System.out.println(map);

        //获取map中所有的key
        Set keys = map.keySet();
        System.out.println("所有的key:"+keys);
        //遍历所有key
        for(Object k:keys){
            System.out.println(k+"---------------->"+map.get(k));
        }

        //判断是否包含某个元素
        System.out.println(map.containsKey("name"));

        map.clear();//clean

    }
}

 

标签:set,Java,Day07,System,println,add,集合,public,out
From: https://blog.csdn.net/Flipped_275/article/details/144407346

相关文章

  • Java 的 G1 垃圾回收流程
    Java的G1垃圾回收流程G1(Garbage-First)垃圾收集器是一种区域化、并发、低延迟的垃圾回收器,适合大堆内存和对暂停时间有严格要求的应用程序。G1的垃圾回收流程主要包括以下阶段:1.堆的区域化分区在G1中,堆被分为多个大小相等的Region,每个Region可以扮演以下角色之一:E......
  • 什么是 Java 中的 logging write barrier?
    什么是Java中的LoggingWriteBarrier?LoggingWriteBarrier是Java垃圾回收器在维护堆引用关系时常用的一种机制。它是一种特殊的写屏障(WriteBarrier),用于记录堆中某些引用的变化情况。该机制的主要目的是协助垃圾回收器在并发或增量标记阶段,正确跟踪对象引用的变化。1.......
  • Java 中的 CMS 和 G1 垃圾收集器如何维持并发的正确性?
    Java中的CMS和G1垃圾收集器如何维持并发的正确性?CMS(ConcurrentMark-Sweep)和G1(Garbage-First)垃圾收集器是两种低延迟的垃圾回收器,它们通过并发阶段与应用线程(Mutator)同时运行,以减少暂停时间。为了维持并发垃圾回收的正确性,二者采取了不同的技术和策略。1.CMS垃圾收集器......
  • Java 的 CMS 垃圾回收器和 G1 垃圾回收器在记忆集的维护上有什么不同?
    Java的CMS垃圾回收器和G1垃圾回收器在记忆集的维护上的不同记忆集(RememberedSet,RSet)是垃圾回收器用来跟踪跨代引用的重要结构,它记录老年代对象对新生代对象的引用。CMS和G1垃圾回收器在记忆集的维护方式和粒度上有显著差异。1.CMS垃圾回收器的记忆集维护1.1粒度......
  • 【最新原创毕设】基于SpringBoot的学生选课管理系统+56695(免费领源码)可做计算机毕业设
    基于Springboot和Vue的学生选课管理系统的设计与实现摘 要本文介绍了一种基于SpringBoot和Vue的学生选课管理系统的设计与实现。该系统旨在提供一个高效、可靠的选课平台,使学生和教职工能够方便地进行课程选择和管理。在系统设计上,我们采用了SpringBoot作为后端框架,利用......
  • (2024最新毕设合集)基于的同城学校二手交易平台|可做计算机毕业设计JAVA、PHP、爬虫、AP
    同城学校二手交易平台设计与实现摘 要利用SpringBoot框架和相关Uni-app技术,设计和实现一个高效、可靠的同城学校二手交易平台。该系统将提供闲置、发布、求购等主要功能,旨在促进二手交易平台的便捷和透明化。本研究首先介绍了同城学校二手交易平台的研究背景和现状,包括同城......
  • 浅谈 Java 垃圾回收机制
    浅谈Java垃圾回收机制文章目录浅谈Java垃圾回收机制一、引言二、垃圾回收算法要解决的问题(一)内存泄漏问题(二)悬空指针问题三、常见的垃圾回收算法(一)标记-清除算法(Mark-SweepAlgorithm)(二)复制算法(CopyingAlgorithm)(三)标记-整理算法(Mark-CompactAlgorithm)(四)分代......
  • Spring 事务相关Java
    深入理解Spring事务一、引言在企业级应用开发中,事务管理是确保数据一致性和完整性的关键环节。Spring框架提供了强大而灵活的事务管理功能,使得开发者能够方便地在各种应用场景中处理事务。本文将深入探讨Spring事务的原理、特性、使用方式,并通过详细的示例代码帮助读......
  • 免费送源码:Java+ssm+springboot springboot高校网上选课系统 计算机毕业设计原创定制
    摘要本论文主要论述了如何使用JAVA语言开发一个高校网上选课系统,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发。在引言中,作者将论述高校网上选课系统的当前背景以及系统开发的目的,后续章节将严格按照软件开发流程,对系统进行......
  • 为什么 Java 中某些新生代和老年代的垃圾收集器不能组合使用?
    为什么Java中某些新生代和老年代的垃圾收集器不能组合使用?在JVM中,新生代和老年代的垃圾收集器是分工协作的。然而,并非所有的新生代和老年代垃圾收集器都能任意组合使用,这是由于它们的设计目标、算法特性和交互方式不兼容所导致的。例如,新生代的ParNew和老年代的ParallelO......