容器/集合

集合

容器

容器的作用和概括

为什么使用容器

数组回顾

数组是一种容器,可以在其中放置一个或一组数据。

优势:是一种简单的线性序列,可以快速的访问数组元素,效率高。

劣势:不灵活,容量事先定义好,不能随着需求的变化而扩容。

数组远远不能满足业务需求。我们需要一种 灵活的 , 容量可以随时扩充的 容器来装载我们的对象。这就是我们今天要学习的容器类,或者叫集合框架;

容器中的接口层次结构

Collection接口

Collection是一个接口,只是规定了一些方法,即作为一个容器就应该具有这些功能。在Collection中并没有任何的可以存储数据的地方,因此只是作为一个规范存在。

添加 (add)|删除(remove) 记数 (size) 包含 (contains)清空 (clear)是否空(isEmpty)

List接口 继承 Collection接口

List作为有序的Collection。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。同样是一个接口也只是提供了一些抽象方法,做出相应的规范

可以存放很多数据,List中的数据有序可以重复获取 get

查询对象出现的索引 indexOf(Object)

Set接口 继承 Collection接口

List作为Collection的子接口,也只是提供了一些抽象方法,做出相应的规范。

可以存放很多数据,但是set中的数据无序不能重复;如果前后数据重复,只存放一个。

Container

集合表示一组对象,称为其元素;

集合(容器)与数组的区别:

**共同点:**储存多个数据

不同点:

数组:1、引用数据类型,是对象数据;

					2、定长,长度一旦确定不可改变;
					3、只能储存多种类型相同的数据;
					4、有序的,有索引;

集合:1、引用数据类型,是对象数据;

2、集合长度可跟随数据的增删进行改动;

3、可以可以任意引用数据类型的数据,存储的多个数据类型可以不同;

4、有些集合有序,有些集合无序,有些可以根据索引进行操作,有些不可以;

代码块:

public class Class001_Container{
   public static void main(String[] args) {
        //1)创建集合类型的实例
        ArrayList list = new ArrayList();

        //2)调用方法实现操作
        list.add("张三");
        System.out.println(list.size());
        list.add(123);
        System.out.println(list.size());
        list.add(false);
        System.out.println(list.size());
        list.add('a');
        System.out.println(list.size());
        list.add(null);
        System.out.println(list.size());

        System.out.println(list);
    }
}

自定义容器类型:

public class Class002_MyContainer {
    public static void main(String[] args) {
        //1.创建集合对象
        MyContainer my = new MyContainer();
        //2.调用方法操作集合
        my.add("aaa");
        System.out.println(my.size());
        my.add("bbb");
        System.out.println(my.size());
        my.add("ccc");
        System.out.println(my.size());

        System.out.println(my.get(0));
        System.out.println(my.get(1));
        System.out.println(my.get(2));
    }
}

//自定义容器类型
class MyContainer{
    private  String[] elementData; //记录集合存储的数据
    private int size; //记录集合中已存储数据个数

    public MyContainer() {

    }

    //添加数据
    public void add(String value) {
        //1)是否是第一次添加
        if(elementData==null || size==0){
            //是,创建数组长度为1
            elementData = new String[1];
            //数据放入数组
            elementData[0] = value;
            //长度+1
            size++;
            return;
        }
        //不是,创建新数组长度为原数组长度+1
        //备份原数组地址
        String[] temp = elementData;
        elementData = new String[size+1];
        //原数组数据拷贝到新数组
        for(int i=0;i<size;i++){
            elementData[i] = temp[i];
        }
        //新数据放在新数组最后
        elementData[size++] = value;
        //长度+1
    }

    //返回集合中数据个数
    public int size(){
        return this.size;
    }

    /**
     * 根据索引获取数据
     * @param index 索引
     * @return index索引位置的数据
     */
    public String get(int index) {
        if(index<0 || index>=size){
            throw new IndexOutOfBoundsException(index+"索引越界啦!!!");
        }
        return elementData[index];
    }

    //根据索引进行修改数据

    //根据索引进行删除数据
}

Collection接口:

概念:

集合层次结构的根接口,规定了一些容器方法,不能存储数据,作为规范存在。

List子接口下的实现类有序可重复,set子接口下的类无序不可重。

遍历方式:

1、foreach

2、迭代器iterator

常用方法:

方法

返回值

作用

add(E e)

boolean

向集合中添加一个元素,如果集合对象被添加操作改变了,则返回 true。E 是元素的数据类型

addAll(Collection c)

boolean

向集合中添加一个元素,如果集合对象被添加操作改变了,则返回 true。E 是元素的数据类型

clear()

void

清除集合中的所有元素,将集合长度变为 0。

contains(Object o)

boolean

判断集合中是否存在指定元素

containsAll(Collection c)

boolean

判断集合中是否包含集合 c 中的所有元素

6. isEmpty()

boolean

判断集合是否为空

iterator()

Iterator

返回一个 Iterator 对象,用于遍历集合中的元素

remove(Object o)

boolean

从集合中删除一个指定元素,当集合中包含了一个或多个元素 o 时,该方法只删除第一个符合条件的元素,该方法将返回 true。

removeAll(Collection c)

boolean

从集合中删除所有在集合 c 中出现的元素(相当于把调用该方法的集合减去集合 c)。如果该操作改变了调用该方法的集合,则该方法返回 true。

retainAll(Collection c)

boolean

从集合中删除集合 c 里不包含的元素(相当于把调用该方法的集合变成该集合和集合 c 的交集),如果该操作改变了调用该方法的集合,则该方法返回 true。

size()

int

返回集合中元素的个数

toArray()

Object[]

把集合转换为一个数组,所有的集合元素变成对应的数组元素。

ArrayList类

什么是ArrayList

ArrayList 类实现了可变数组的大小,存储在内的数据称为元素。它还提供了快速基于索引访问元素的方式,对尾部成员的增加和删除支持较好。

优缺点

优点:允许对集合中的元素进行快速的随机访问。

缺点:向 ArrayList 中插入与删除元素的速度相对较慢。

三种构造器

1.ArrayList()

构造一个初始容量为十的空列表。

2.ArrayList(Collection<? extends E> c)

构造一个包含指定集合的元素的列表,按照它们由集合的迭代器返回的顺序。

3.ArrayList(int initialCapacity)

构造具有指定初始容量的空列表。

常用方法

方法

返回值

作用

get(int index)

E

获取此集合中指定索引位置的元素,E 为集合中元素的数据类型

index(Object o)

int

返回此集合中第一次出现指定元素的索引,如果此集合不包含该元素,则返回 -1

lastIndexOf(Object o)

int

返回此集合中最后一次出现指定元素的索引,如果此集合不包含该元素,则返回 -1

set(int index, Eelement)

E

将此集合中指定索引位置的元素修改为 element 参数指定的对象。此方法返回此集合中指定索引位置的原元素

subList(int fromlndex, int tolndex)

List

返回一个新的集合,新集合中包含 fromlndex 和 tolndex 索引之间的所有元素。包含hanfromlndex 处的元素,不包含 tolndex 索引处的元素

代码

调用 Product 类的构造函数实例化三个对象,并将 Product 对象保存至 ArrayList 集合中。最后遍历该集合,输出商品信息。

subList() 方法的具体用法

LinkedList类

什么是LinkedList

LinkedList 类采用链表结构保存对象

优缺点

优点:便于向集合中插入或者删除元素。

缺点:检索集合中特定索引位置的元素的速度相对较慢

除了继承Collection/List接口的方法

方法

返回值

作用

addFirst(E e)

void

将指定元素添加到此集合的开头

addLast(E e)

void

将指定元素添加到此集合的末尾

getFirst()

E

返回此集合的第一个元素

getLast()

E

返回此集合的最后一个元素

removeFirst()

E

删除此集合中的第一个元素

removeLast()

E

删除此集合中的最后一个元素

代码

//仓库管理系统中要记录入库的商品名称,并且需要输出第一个录入的商品名称和最后—个商品名称。下面使用 LinkedList 集合来完成这些功能;

public class Test {
    public static void main(String[] args) {
        LinkedList<String> products = new LinkedList<String>(); // 创建集合对象
        String p1 = new String("六角螺母");
        String p2 = new String("10A 电缆线");
        String p3 = new String("5M 卷尺");
        String p4 = new String("4CM 原木方板");
        products.add(p1); // 将 p1 对象添加到 LinkedList 集合中
        products.add(p2); // 将 p2 对象添加到 LinkedList 集合中
        products.add(p3); // 将 p3 对象添加到 LinkedList 集合中
        products.add(p4); // 将 p4 对象添加到 LinkedList 集合中
        String p5 = new String("标准文件夹小柜");
        products.addLast(p5); // 向集合的末尾添加p5对象
        
        System.out.print("*************** 商品信息 ***************");
        System.out.println("\n目前商品有:");

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

        System.out.println("\n第一个商品的名称为:" + products.getFirst());
        System.out.println("最后一个商品的名称为:" + products.getLast());
        products.removeLast(); // 删除最后一个元素
        System.out.println("删除最后的元素,目前商品有:");
        for (int i = 0; i < products.size(); i++) {
            System.out.print(products.get(i) + "\t");
       }
    }
}

与ArrayList 类的区别

ArrayList 与 LinkedList 都是 List 接口的实现类,因此都实现了 List 的所有未实现的方法,只是实现的方式有所不同。

ArrayList 是基于动态数组数据结构的实现,访问元素速度优于 LinkedList。LinkedList 是基于链表数据结构的实现,占用的内存空间比较大,但在批量插入或删除数据时优于 ArrayList。

对于快速访问对象的需求,使用 ArrayList 实现执行效率上会比较好。需要频繁向集合中插入和删除元素时,使用 LinkedList 类比 ArrayList 类效果高。

集合

数组特点

存储多个相同数据类型

拥有索引,查询效率高

数组长度不变

集合特点

存储任意引用数据类型的数据

根据需求修改容量,增删数据

Collection

**List :**有序,可重复

ArrayList

有序,可重复

底层结构 : 数组

特点 : 查询效率高,增删效率低(涉及到了创建新数组,拷贝数据)

应用场景 : 适合应用在想要根据索引进行操作,有序可重复前提下,大量做查询,少量做增删

新增方法 :一些要操作索引的方法

遍历方式 :1) for 2) foreach 3)iterator

LinkedList

LinkedList : 并允许所有元素(包括null )。

有序,可重复

底层结构 : 双向链表

特点 : 增删效率高,查询效率低

应用场景 : 适合应用在大量做增删,少量做查询的情况

新增方法 : 新增了一些操作链表头尾的方法

遍历方式 : 1) for 2) foreach 3)iterator 4)listInterator

请注意,此实现不同步,线程不安全。

Vector (了解)

Set : 无序,不可重复,唯一的,去重的

HashSet

TreeSet

Map(映射的集合)

HashMap

TreeMap

Hashtable

Properties

Collections : 操作集合工具类

泛型

特点:

泛型可以在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高了代码的重用率。泛型本质上是提供类型的“类型参数”,也就是参数化类型

jdk1.5新特性

参数化类型 : 把数据类型作为参数传递

使用方式 : <数据类型>

优点

增强程序的稳定性与可读性

严谨,健壮,避免类型转换异常的出现

便于后期维护

注意

		定义类型的时候定义了泛型的使用,在使用类型的时候,才可以通过泛型传递数据类型

发生在编译期间,运行期间泛型的使用没有意义-->泛型擦除

泛型传递的类型必须为引用数据类型

手写linkedlist

/*
    通过单向链表实现LinkedList类型 : 了解
    toString : 返回对象的字符串表现形式
 */

public class Class003_MyLinked {
    public static void main(String[] args) {
        //空链表
        MyLinkedList list = new MyLinkedList();
        System.out.println(list.size());
        //list.add("aa");
        System.out.println(list.size());
        //list.add("bb");
        System.out.println(list.size());
        //list.add("cc");
        System.out.println(list.size())
        //System.out.println(list.get(0));
        //System.out.println(list.get(1));
        //System.out.println(list.get(2));
        //System.out.println(list.get(3));
        System.out.println(list);
    }
}
//自定义容器类型

class MyLinkedList{

    private Node head; //记录链表的首节点
    private int size; //记录集合中数据的个数
    public MyLinkedList() {
    }
    /**
     * 添加数据
     * @param value 要添加的数据
     */
    public void add(Object value) {
        //创建新节点,存储要添加的数据
        Node  newNode = new Node(value,null);
        //是否存在链表头
        if(head==null && size==0){
            //不存在,当前新节点作为链表头节点
            head = newNode;
            //长度+1
            size++;
            return;
        }
        //存在链表头节点,遍历,找到原链表的最后一个节点
        Node temp = head; //临时变量,局部变量,作用就是用来遍历链表,指向最新的节点,直到最后一个节点结束(next属性值为null)
        while(temp.getNext()!=null){
            temp = temp.getNext();
        }
        //新节点挂上去
        temp.setNext(newNode);
        //长度+1
        size++;
    }
    /**
     * 获取集合中数据的个数
     * @return 数据个数
     */
    public int size(){
        return this.size;
    }
    /**
     * 根据索引获取数据
     * @param index 索引
     * @return 指定索引位置的数据
     */
    public Object get(int index) {
        if(index<0 || index>=size){
            throw new IndexOutOfBoundsException(index+"越界了。。。");
        }

        //遍历
        Node temp = head;
        for(int i = 0;i<=size-1;i++){
            if(i==index){ //当前temp所指向的节点的索引就是你要的索引
                return temp.getData(); //返回当前节点存储的数据
            }
            temp = temp.getNext();
        }
        return null;
    }

    @Override
    public String toString() {
        if(head==null && size==0){
            return "[]";
        }

        StringBuilder sb = new StringBuilder("[");
        Node temp = head;
        while(true){
            sb.append(temp.getData());
            sb.append(", ");
            if(temp.getNext()==null){
                break;
            }
            temp = temp.getNext(); //temp指向下一个节点
        }
        sb.delete(sb.length()-2,sb.length()); //结束索引位置一般不包含
        sb.append("]");
        return sb.toString();
    }
}
//节点

class Node{
    private Object data;
    private Node next;

    public Node() {
    }

    public Node(Object data, Node next) {
        this.data = data;
        this.next = next;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值