java基础---集合(1)

一、 基本概念

  • 集合、数组都是对多个数据进行存储操作的结构,简称Java容器
  • 数组:长度确定,类型确定,对于添加、删除、插入等操作效率不高,元素有序可重复
  • Java中集合框架顶层框架是:java.util.Collection集合 和 java.util.Map集合

二、Collection接口的常用方法

  • Collection 接口是 ListSet Queue 接口的父接口,该接口里定义的方法既可用于操作 Set 集合,也可用于操作 List Queue 集合 JDK不提供此接口的任何直接实现,而是提供更具体的子接口(如: SetList)实现。
  • Java5 之前, Java 集合会丢失容器中所有对象的数据类型,把所有对象都当成 Object 类型处理; 从 JDK 5.0 增加了泛型以后, Java 集合可以记住容器中对象的数据类型。
  • 向Collection接口的实现类的对象中添加数据obj时,要求obj所在类要重写equals()和hashcode().
方法声明 功能介绍
boolean add(E e); 向集合中添加对象
boolean addAll(Collection<? extends E>c) 用于将参数指定集合c中的所有元素添加到当前集合中
boolean contains(Object o); 判断是否包含指定对象
boolean containsAll(Collection<?> c) 判断是否包含参数指定的所有对象
boolean retainAll(Collection<?> c) 保留当前集合中存在且参数集合中存在的所有对象,当前集合变为差集
boolean remove(Object o); 从集合中删除对象,只会删除找到的第一个元素
boolean removeAll(Collection<?> c) 从集合中删除参数指定的所有对象
void clear(); 清空集合
int size(); 返回包含对象的个数
boolean isEmpty(); 判断是否为空
boolean equals(Object o) 判断是否相等
int hashCode() 获取当前集合的哈希码值
Object[] toArray() 将集合转换为数组
Iterator iterator() 获取当前集合的迭代器
package com.atguigu.java;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

public class CollectionTest {


    @Test
    public void test1(){
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
//        Person p = new Person("Jerry",20);
//        coll.add(p);
        coll.add(new Person("Jerry",20));
        coll.add(new String("Tom"));
        coll.add(false);
        //1.contains(Object obj):判断当前集合中是否包含obj
        //我们在判断时会调用obj对象所在类的equals()。
        boolean contains = coll.contains(123);
        System.out.println(contains);
        System.out.println(coll.contains(new String("Tom")));
//        System.out.println(coll.contains(p));//true
        System.out.println(coll.contains(new Person("Jerry",20)));//false -->true

        //2.containsAll(Collection coll1):判断形参coll1中的所有元素是否都存在于当前集合中。
        Collection coll1 = Arrays.asList(123,4567);
        System.out.println(coll.containsAll(coll1));
    }

    @Test
    public void test2(){
        //3.remove(Object obj):从当前集合中移除obj元素。
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new Person("Jerry",20));
        coll.add(new String("Tom"));
        coll.add(false);

        coll.remove(1234);
        System.out.println(coll);

        coll.remove(new Person("Jerry",20));
        System.out.println(coll);

        //4. removeAll(Collection coll1):差集:从当前集合中移除coll1中所有的元素。
        Collection coll1 = Arrays.asList(123,456);
        coll.removeAll(coll1);
        System.out.println(coll);


    }

    @Test
    public void test3(){
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new Person("Jerry",20));
        coll.add(new String("Tom"));
        coll.add(false);

        //5.retainAll(Collection coll1):交集:获取当前集合和coll1集合的交集,并返回给当前集合
//        Collection coll1 = Arrays.asList(123,456,789);
//        coll.retainAll(coll1);
//        System.out.println(coll);

        //6.equals(Object obj):要想返回true,需要当前集合和形参集合的元素都相同。
        Collection coll1 = new ArrayList();
        coll1.add(456);
        coll1.add(123);
        coll1.add(new Person("Jerry",20));
        coll1.add(new String("Tom"));
        coll1.add(false);

        System.out.println(coll.equals(coll1));


    }

    @Test
    public void test4(){
        Collection coll = new ArrayList();
        coll.add(123);
        coll.add(456);
        coll.add(new Person("Jerry",20));
        coll.add(new String("Tom"));
        coll.add(false);

        //7.hashCode():返回当前对象的哈希值
        System.out.println(coll.hashCode());

        //8.集合 --->数组:toArray()
        Object[] arr = coll.toArray();
        for(int i = 0;i < arr.length;i++){
            System.out.println(arr[i]);
        }

        //拓展:数组 --->集合:调用Arrays类的静态方法asList()
        List<String> list = Arrays.asList(new String[]{"AA", "BB", "CC"});
        System.out.println(list);

        List arr1 = Arrays.asList(new int[]{123, 456});
        System.out.println(arr1.size());//1

        List arr2 = Arrays.asList(new Integer[]{123, 456});
        System.out.println(arr2.size());//2

        //9.iterator():返回Iterator接口的实例,用于遍历集合元素。放在IteratorTest.java中测试

    }
}

三、Iterator迭代器

  • java.util.Collection接口继承Iterator接口,因此所有实现Collection接口的实现类都可以使用该迭代器对象,提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节
  • 所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象
  • Iterator 仅用于遍历集合, Iterator 本身并不提供承装对象的能力。如果需要创建Iterator 对象,则必须有一个被迭代的集合。
  • 集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。 在调用it.next()方法之前必须要调用it.hasNext()进行检测。若不调用,且下一条记录无效,直接调用it.next()会抛出NoSuchElementException异常 
  • Iterator可以删除集合的元素, 但是是遍历过程中通过迭代器对象的remove方法, 不是集合对象的remove方法
  • 如果还未调用next()或在上一次调用 next 方法之后已经调用了 remove 方法,再调用remove都会报IllegalStateException。 
方法声明 功能介绍
boolean hasNext() 判断集合中是否有可以迭代/访问的元素
E next() 用于取出一个元素并指向下一个元素
void remove() 用于删除访问到的最后一个元素
      ////hasNext():判断是否还有下一个元素,iterator指针刚开始在首部的前一个位置
        while(iterator.hasNext()){
            //next():①指针下移 ②将下移以后集合位置上的元素返回
            System.out.println(iterator.next());
        }
  • 使用 foreach 循环遍历集合元素  
    for(集合元素的类型 局部变量 : 集合对象)
    • Java 5.0 提供了 foreach 循环迭代访问 Collection和数组。
    • 遍历操作不需获取Collection或数组的长度,无需使用索引访问元素
    • 遍历集合的底层调用Iterator完成操作。
    • foreach还可以用来遍历数组。
@Test
    public void test3(){
        String[] arr = new String[]{"MM","MM","MM"};
//        //方式一:普通for赋值
//        for(int i = 0;i < arr.length;i++){
//            arr[i] = "GG";
//        }
        //方式二:增强for循环
        for(String s : arr){
            s = "GG";
        }
        for(int i = 0;i < arr.length;i++){
            System.out.println(arr[i]);  //arr数组内的内容没有变化
        }
    }

四、List接口

  • java.util.List集合是Collection集合的子集合,该集合中允许有重复的元素并且有先后放入次序。该集合的主要实现类有:ArrayList类、LinkedList类、Stack类、Vector
  • ArrayList的底层是采用动态数组进行数据管理的,支持下标访问,增删元素不方便。
  • LinkedList的底层是采用双向链表进行数据管理的,访问不方便,增删元素方便
  • Stack的底层是采用动态数组进行数据管理的,该类主要用于描述一种具有后进先出特征的数据结构,叫做栈(last in first out LIFO)
  • Vector的底层是采用动态数组进行数据管理的,该类与ArrayList类相比属于线程安全的类,效率比较低,以后开发中基本不用。 sychronized

1. ArrayList源码

  •  jdk 7情况下
    •  ArrayList list = new ArrayList();//底层创建了长度是10的Object[]数组elementData
    • 如果底层elementData数组容量不够,则扩容,默认情况下,扩容为原来的容量的1.5倍,同时需要将原有数组中的数据复制到新的数组中。
    • 结论:建议开发中使用带参的构造器:ArrayList list = new ArrayList(int capacity)
  •  jdk 8中ArrayList的变化:
    •  ArrayList list = new ArrayList();//底层Object[] elementData初始化为{}.并没有创建长度为10的数组
    • 第一次调用add()时,底层才创建了长度10的数组,并将数据添加到elementData[0] 
  • 小结:jdk7中的ArrayList的对象的创建类似于单例的饿汉式,而jdk8中的ArrayList的对象的创建类似于单例的懒汉式,延迟了数组的创建,节省内存。

2. LinkedList的源码

  • LinkedList list = new LinkedList(); 内部声明了Node类型的first和last属性,默认值为null,不涉及初始容量
  • Node定义为:体现了LinkedList的双向链表:
  • 常用方法:
    • void addFirst(Object obj)
    • void addLast(Object obj)
    • Object getFirst()
    • Object getLast()
    • Object removeFirst()
    • Object removeLast()
        
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;

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

3. Vector的源码

  • jdk7和jdk8中通过Vector()构造器创建对象时,底层都创建了长度为10的数组。
  • jdk1.0有的,线程安全类,在扩容方面,默认扩容为原来的数组长度的2倍。
  • 常用方法:
    • void addElement(Object obj)
    • void insertElementAt(Object obj,int index)
    • void setElementAt(Object obj,int index)
    • void removeElement(Object obj)
    • void removeAllElements()

4.Stack的源码

public class Stack<E> extends Vector<E> {  //继承Vector
   
    public Stack() {
    }

  //入栈
    public E push(E item) {
        addElement(item);  //调用父类的add方法

        return item;
    }

   //出栈  线程安全
    public synchronized E pop() {
        E       obj;
        int     len = size();

        obj = peek();
        removeElementAt(len - 1);

        return obj;
    }

  //查看栈顶元素
    public synchronized E peek() {
        int     len = size();

        if (len == 0)
            throw new EmptyStackException();
        return elementAt(len - 1);
    }

   //栈是否为空
    public boolean empty() {
        return size() == 0;
    }

   //返回出栈索引
    public synchronized int search(Object o) {
        int i = lastIndexOf(o);

        if (i >= 0) {
            return size() - i;
        }
        return -1;
    }

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = 1224463164541339165L;
}

5. list常用方法

方法声明 功能介绍
void add(int index, E element) 向集合中指定位置添加元素
boolean addAll(int index, Collection<? extends E> c) 向集合中添加所有元素
E get(int index) 从集合中获取指定位置元素
int indexOf(Object o) 查找参数指定的对象
int lastIndexOf(Object o) 反向查找参数指定的对象
E set(int index, E element) 修改指定位置的元素,返回的是修改前元素
E remove(int index) 重载,删除指定位置的元素, 父类的remove是删除元素
List subList(int fromIndex, int toIndex) 用于获取子List
@Test
public void testListRemove() {
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
updateList(list);
System.out.println(list);// 1,2
}
private static void updateList(List list) {
list.remove(2);
}

 五、 Queue集合

  • java.util.Queue集合是Collection集合的子集合,与List集合属于平级关系。
  • 该集合的主要用于描述具有先进先出特征的数据结构,叫做队列(first in first out FIFO)
  • 该集合的主要实现类是LinkedList类,因为该类在增删方面比较有优势。
    方法声明 功能介绍
    boolean offer(E e) 将一个对象添加至队尾,若添加成功则返回true
    E poll() 从队首删除并返回一个元素
    E peek() 返回队首的元素(但并不删除)


posted @ 2020-09-25 16:35  forever_fate  阅读(139)  评论(0)    收藏  举报