你的位置:首页 > 信息动态 > 新闻中心
信息动态
联系我们

第七章 集合(一)

2021-12-6 0:08:44

目录

1、集合的概述

 2、Collection(单列)

1. 单个集合的方法

 2. 多个集合之间

3. 集合转数组

3、List集合概述

1. ArrayList

1. 添加元素的过程和扩容机制

2. 常用方法

 3. removeRange()方法

4. 比较器

2. LinkedList

3. Vorter

4. List集合的遍历(ArrayLIst为例)

1. for循环

2. 增强for循环

3. Iterator (迭代器)


1、集合的概述

       在程序运行的过程中,数据的数量随时发生改变,需要的存储结构也随之改变,以解决一些特殊的需求, 但是因为数组长度不变且类型固定的不足,以此我们引用集合,来满足数组的不足。

 2、Collection(单列)

java中集合类默认使用泛型,如果没有定义集合中存储的数据类型,默认数据类型为object。

创建方式:

     Callection  c = new ArrayList();  // 多态:运行看右,编译看左

   c.add("a");     c.add(1);      c.add(true);

    使用泛型:

Callection<T>  c  =  new ArrayList<T>(); //  T 可以使用任何类型,如String、Integer、Double等

Callection<String>  c  =  new ArrayList<String>();

使用泛型,来为集合指明数据类型,类型统一就不会出现转型问题。

注:<E>类型的参数化或参数的类型化

常用方法

1. 单个集合的方法

添加元素(一次添加一个)c.add();

清空(所有元素)  c.clear();

是否包含指定元素(如a) c.contains("a');  返回值  boolean

是否为空   c.isEmpty();     返回值 boolean

删除指定元素   c.remove("a");   返回值 boolean

集合长度   c.size();     返回值   int

public class Demo1 {
    public static void main(String[] args) {
//        Collection c = new ArrayList();
        Collection<String> c = new ArrayList<String>();
        //向集合添加元素
        c.add("a");
        c.add("b");
        c.add("c");
        c.add("d");
        /*c.add(1);
        c.add(true);*/
        //清空集合
        //c.clear();
        //是否包含指定元素
        System.out.println(c.contains("c"));//true 返回值:boolean
        //判断是否为空
        System.out.println(c.isEmpty());//false
        //删除指定元素
        System.out.println(c.remove("a"));//true
        //集合长度
        System.out.println(c.size());//3
        System.out.println(c);//[b, c, d]
        //添加c1集合的所有元素(包括重复的元素)
    }
}

 2. 多个集合之间

将c2集合中的元素添加到c1集合中去(可添加重复的元素) 

                                                    c1.addAll(c2);

c1集合中是否包含c2集合中的元素

                                                   c1.containsAll(c2);

删除c1集合中c2集合中的元素   

                                                   c1.removeAll(c2);    

c1集合和c2集合中的交集(内容改变为true,无交集也返回true;内容不变返回false,当c1集合中的元素完全等于c2集合中的元素时,为false

                                                     c1.retainAll(c2);

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

public class Demo2 {
    public static void main(String[] args) {
        Collection<String> c1 = new ArrayList<String>();
        c1.add("a");
        c1.add("b");
        c1.add("c");
        c1.add("d");
        Collection<String> c2 = new ArrayList<String>();
        c2.add("g");
        c2.add("e");
        c2.add("f");
        //向c1中添加c2中的元素,可重复。
        c1.addAll(c2);
        System.out.println(c1);//[a, b, c, d, g, e, f]
        //c1集合中是否包含c2中的元素
        System.out.println(c1.containsAll(c2)); //true
        System.out.println(c1);//[a, b, c, d, g, e, f]
        //删除c1中c2的元素
        System.out.println(c1.removeAll(c2)); //true
        System.out.println(c1);//[a, b, c, d]
        //c1和c2集合中交集部分
        System.out.println(c1.retainAll(c2)); //true
        System.out.println(c1);//[]
      
    }
}

3. 集合转数组

     默认转数组:object类型

                          object[] obj = c1.toArray();

      String[]   str   =  c1.toArray(new String[c1.size()]);    String类型

 //集合转数组
        c1.add("a");
        c1.add("b");
        c1.add("c");
        c1.add("d");
        Object[] obj = c1.toArray();
        System.out.println(Arrays.toString(obj));//[a, b, c, d]
        System.out.println(obj.length);//4
        String[] str = c1.toArray(new String[c1.size()]);
        System.out.println(Arrays.toString(str));//[a, b, c, d]
        System.out.println(str.length);//4

3、List集合概述

ArrayList 

    数组列表(存储连续,长度可变)

    特点:查询快,对中间插删操作效率低,可以存储重复的元素。

LinkedList 

    链表列表

    特点:查询慢,从头结点或尾节点开始查询,但是对中间进行插删操作效率高

Vector   

    数组列表、线程安全(使用同步锁)

    特点:查询快,对中间插删操作效率低,可以存储重复的元素

1. ArrayList

        ArrayList<String>  alist = new ArrayList<String>();

创建对象时,不会创建数组,第一次添加时默认创建一个容量为10的数组。

       ArrayList<String>  alist = new ArrayList<String>(20);

创建对象时,创建一个指定容量的数组

transient  object[]   elementDate;  底层存储数据的数组

1. 添加元素的过程和扩容机制

add(E e)     向末尾添加元素进来

概述:

         ArrayList在创建对象是不会创建数组,当第一次添加元素时,这时会创建一个容量为10的数组,(默认创建,也可以在创建对象时,创建指定容量的数组),继续添加的前会判断元素添加进来后,元素是否能够放下,如果可以,则可以直接进入数组,如果不可以,则会创建一个新的数组,并且将新数组的容量是原来数组容量的1.5 倍(使用grow())。

源码:
                    public boolean add(E e) {
                                ensureCapacityInternal(size + 1);  // 检测容量
                                elementData[size++] = e;
                                return true;
                            }

                                       
                     if (minCapacity - elementData.length > 0) 添加后的长度-数组长度>0
                             grow(minCapacity);    数组扩容方法    

                             
              private void grow(int minCapacity) {
                        // overflow-conscious code
                        int oldCapacity = elementData.length;
                        int newCapacity = oldCapacity + (oldCapacity >> 1);//扩容为原来的1.5倍
                        if (newCapacity - minCapacity < 0)
                            newCapacity = minCapacity;
                        if (newCapacity - MAX_ARRAY_SIZE > 0) 最大上限 int最大值-8
                            newCapacity = hugeCapacity(minCapacity);
                        // minCapacity is usually close to size, so this is a win:
                        elementData = Arrays.copyOf(elementData, newCapacity);
              }

2. 常用方法

  • 向指定位置添加元素(指定位置小于等于alist.size())             alist.add(1, "D");
  • 判断集合是否存在指定元素                                                      alist.contains("a");
  • 指定元素第一次出现在集合的位置                                           alist.indexOf("b");
  • 指定元素最后一次出现的位置                                                  alist.lastIndexOf("b");
  • 判断集合是否为空                                                                     alist.isEmpty();
  • 删除指定位置的元素                                                                 alist.remove(2);
  •  删除指定元素                                                                           alist.remove("a");
  • 将指定索引替换成指定元素                                                       alist.set(3, "F");
  • 获取指定索引的内容                                                                  alist.get(2));
  • 集合大小的长度                                                                         alist.size();
  • 集合转数组                                      String[] str = alist.toArray(new String[alist.size()]);
public class Demo {
    public static void main(String[] args) {
//        ArrayList<String> alist = new ArrayList();
        ArrayList<String> alist = new ArrayList<String>(9);
        alist.add("a");
        alist.add("b");
        alist.add("c");
        alist.add("d");
        alist.add("b");
        alist.add("a");
        System.out.println(alist);//[a, b, c, d, b, a]
        //向指定位置添加内容
        alist.add(1, "D");
        System.out.println(alist);//[a, D, b, c, d, b, a]
        //判断集合是否存在指定元素
        System.out.println(alist.contains("a"));//true
        //指定元素第一次出现在集合的位置
        System.out.println(alist.indexOf("b"));//2
        //指定元素最后一次出现的位置
        System.out.println(alist.lastIndexOf("b"));//5
      // 判断集合是否为空
        System.out.println(alist.isEmpty());//false
      //删除指定位置的元素
        alist.remove(2);
        System.out.println(alist);//[a, D, c, d, b, a]
    //删除指定元素
        alist.remove("a");
        System.out.println(alist);//[D, c, d, b, a]
     //将指定索引替换成指定元素
        alist.set(3, "F");
        System.out.println(alist);//[D, c, d, F, a]
    //获取指定索引的内容
        System.out.println(alist.get(2));//d
    //集合大小的长度
        System.out.println(alist.size());//5
        System.out.println(alist);//[D, c, d, F, a]
    //集合转数组
        String[] str = alist.toArray(new String[alist.size()]);
        System.out.println(Arrays.toString(str));//[D, c, d, F, a]

    }
}

 3. removeRange()方法

           删除指定区间的集合元素

public class MyArrayList<E> extends ArrayList{
	
	public static void main(String[] args) {
		MyArrayList<String> alist = new MyArrayList<String>();
		                    alist.removeRange(0, 5);//受保护的方法,在不同的子类访问
		            
	}

}

4. 比较器

(1)new + 接口() 创建了一个匿名内部类对象,Comparator 传递一个比较器。

alist.sort(new Comparator<User>() {
            @Override
            public int compare(User o1, User o2) {
                return o1.getId() - o2.getId();
            }
        });

(2)自定义比较器(例:用户比较器)

//用户类
public class User {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Usre{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }
}
import java.util.Comparator;
//用户比较器: 
public class UserComparator<U> implements Comparator<User>{

    @Override
    public int compare(User o1,User o2) {
        return o1.getId() - o2.getId();
    }
}
//Test类
public class Test {
    public static void main(String[] args) {
        ArrayList<User> alist = new ArrayList<>();
        User user1 = new User(1,"张三1");
        User user2 = new User(2,"张三2");
        User user3 = new User(3,"张三3");
        User user4 = new User(4,"张三4");
        User user5 = new User(5,"张三5");
        alist.add(user5);
        alist.add(user3);
        alist.add(user1);
        alist.add(user4);
        alist.add(user2);
        //new + 接口() 创建了一个匿名内部类对象,Comparator 传递一个比较器
       /* alist.sort(new Comparator<User>() {
            @Override
            public int compare(User o1, User o2) {
                return o1.getId() - o2.getId();
            }
        });*/
        alist.sort(new UserComparator());
    }
}

2. LinkedList

特点:存储重复元素,按照添加顺序进行排放

创建: LinkedList<String> llist = new LinkedList<>();

Node 节点  E item; 数据    Node<E> next;  后指针    Node<E> prev;  前指针

源码:

Node<E> node(int index) {
    // assert isElementIndex(index);

    if (index < (size >> 1)) {   //索引小于长度的一半, 从头结点向后找
        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;
    }
}

3. Vorter

底层也是数组实现,是线程安全(使用同步锁),方法与ArrayList类似。

源码:
               public synchronized boolean add(E e) {
                    modCount++;
                    ensureCapacityHelper(elementCount + 1);
                    elementData[elementCount++] = e;
                    return true;
                }

创建:

Vector<String> v = new Vector<String>();

4. List集合的遍历(ArrayLIst为例)

1. for循环

    支持在遍历操作中进行删除集合中的元素,注意所以的变化(会发生数组的越界)


import java.util.ArrayList;

public class Demo {
    public static void main(String[] args) {
        ArrayList<String> alist = new ArrayList<>();
        alist.add("a");
        alist.add("b");
        alist.add("c");
        alist.add("d");
        alist.add("a");
        alist.add("a");
        
        /*
        第一种 : for循环
        支持在遍历操作中进行删除集合中的元素,注意所以的变化(会发生数组的越界)
         */
        for (int i = 0; i < alist.size(); i++) {
            System.out.print(alist.get(i) + " ");
        }
        System.out.println();//a b c d a a 
    
    }
}

2. 增强for循环

  不支持在遍历集合时进行删除集合中的元素,否则会抛出并发修改异常 
       (concurrentModificationException)

注:只允许删除一次,删除的同时使用break结束循环

import java.util.ArrayList;

public class Demo {
    public static void main(String[] args) {
        ArrayList<String> alist = new ArrayList<>();
        alist.add("a");
        alist.add("b");
        alist.add("c");
        alist.add("d");
        alist.add("a");
        alist.add("a");
        
        /*
        第二种:  增强for循环
        不支持在遍历集合时进行删除集合中的元素,否则会抛出并发修改异常 
       (concurrentModificationException)
         */
       for (String item: alist
             ) {

            System.out.print(item);
        }

    }
}

3. Iterator (迭代器)

1. 调用Iterator(),返回一个迭代器对象

package javacollection.day3;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;

public class Demo1 {
    public static void main(String[] args) {
        ArrayList<String> alist = new ArrayList<>();
        alist.add("a");
        alist.add("b");
        alist.add("c");
        alist.add("d");
        alist.add("a");
        alist.add("a");

       /*
       第三种:迭代器
       Iterator<E>(从前向后遍历删除操作) 和 ListIterator<E> 
(从后往前进行遍历删除操作)两种
        */
        Iterator<String> it = alist.iterator();
//调用Iterator()方法,返回一个迭代器对象
        while (it.hasNext()){
            String its = it.next();
            if(its.equals("a")){
                it.remove();//删除当前指针指定的那个元素
            }
        }
        System.out.println(alist);//[b, c, d]

        ListIterator<String> iter = alist.listIterator(alist.size());
        //给出集合的长度,逆序输出集合中的元素,ListIterator只能遍历List接口下的集合
        while (iter.hasPrevious()){
            String its = iter.previous();
            if(its.equals("b")){
                iter.remove();
            }

        }
        System.out.println(alist);//[c, d]
    }
}

 2. 给出集合的长度,逆序输出集合中的元素,ListIterator只能遍历List接口下的集合

package javacollection.day3;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;

public class Demo1 {
    public static void main(String[] args) {
        ArrayList<String> alist = new ArrayList<>();
        alist.add("a");
        alist.add("b");
        alist.add("c");
        alist.add("d");
        alist.add("a");
        alist.add("a");

        ListIterator<String> iter = alist.listIterator(alist.size());
        //给出集合的长度,逆序输出集合中的元素,ListIterator只能遍历List接口下的集合
        while (iter.hasPrevious()){
            String its = iter.previous();
            if(its.equals("b")){
                iter.remove();
            }

        }
        System.out.println(alist);//[a, c, d, a, a]
    }
}