集合Ⅰ

Collection集合

Collection层次结构中的根接口。Collection表示一组对象,这些对象也称为collection的元素。

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

public class Demo1 {
    public static void main(String[] args) {
		//我有3个学生,请把这个3个学生的信息存储到数组中,并遍历数组,获取得到每一个学生信息。
		//学生类中有name(姓名)和age(年龄)两个属性,并重写了toString方法
        Student s1=new Student("张三",15);
        Student s2=new Student("李四",16);
        Student s3=new Student("王五",15);
        Student[] students=new Student[3];
        //数组作为容器,有一些不便之处
        //数组长度一旦确定,不便在数组中增删元素
        //Java为我们提供了一种容器,集合。它对容器中的元素进行增删改查操作很方便
        //我们通过多态的形式来创建Collection接口的对象
        Collection collection=new ArrayList();
        /*
        boolean add(E e)
        确保此collection包含指定的元素(可选操作)。如果此collection由于调用而发生更改,则返回true。
        */
        collection.add(s1);
        collection.add(s2);
        collection.add(s3);
        System.out.println(collection);
    }
}

class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.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;
    }

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

/*
运行结果:
[Student{name='张三', age=15}, Student{name='李四', age=16}, Student{name='王五', age=15}]
*/

数组与集合的区别:

  • 数组的长度一旦确定,不可变。而集合的长度可以改变。
  • 集合的长度可变 数组既可以基本类型数据,也可以存储引用类型数据。集合只能存储引用类型数据。
  • 数组只能存储同一种数据类型的数据,集合可以存储多种数据类型的数据

方法

boolean add(E e)
确保此collection包含指定的元素(可选操作)。如果此collection由于调用而发生更改,则返回true。
boolean addAll(Collection<? extends E> c)
将指定collection中的所有元素都添加到此collection中(可选操作)。

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

public class Demo {
    public static void main(String[] args) {
        Collection collection1=new ArrayList();
        //如果add方法存储基本数据类型,会将这些基本数据类型进行自动装箱,然后再存储
        //也就是说,集合中存储的依旧是引用数据类型
        collection1.add(100);
        collection1.add(200);
        collection1.add(300);
        System.out.println(collection1);

        Collection collection2=new ArrayList();
        collection2.add(1000);
        collection2.add(2000);
        collection2.add(3000);
        
        collection1.addAll(collection2);
        //addAll方法只会改变collection1,即调用者的集合。而collection2不会发生改变。
        System.out.println(collection1);
        System.out.println(collection2);
    }
}
/*
运行结果:
[100, 200, 300]
[100, 200, 300, 1000, 2000, 3000]
[1000, 2000, 3000]
*/

void clear()
移除此collection中的所有元素(可选操作)。
boolean remove(Object o)
从此collection中移除指定元素的单个实例,如果存在的话(可选操作)。
boolean removeAll(Collection<?> c)
移除此collection中那些也包含在指定collection中的所有元素(可选操作)。

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

public class Demo {
    public static void main(String[] args) {
        Collection collection=new ArrayList();
        collection.add(100);
        collection.add(200);
        collection.add(300);

        collection.remove(100);
        System.out.println(collection);
        
        collection.clear();
        System.out.println(collection);

        Collection collection1=new ArrayList();
        collection1.add(100);
        collection1.add(200);
        collection1.add(300);
        Collection collection2=new ArrayList();
        collection2.add(100);
        collection2.add(2000);
        collection2.add(3000);
        //移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。即移除交集元素
        //移除一个及一个以上返回则true
        boolean b = collection1.removeAll(collection2);
        System.out.println(b);
        //同样的,只有collection1中的元素发生改变,collection2中的元素不变
        System.out.println(collection1);
        System.out.println(collection2);
    }
}
/*
运行结果:
[200, 300]
[]
true
[200, 300]
[100, 2000, 3000]
*/

boolean contains(Object o)
如果此collection包含指定的元素,则返回true。
boolean containsAll(Collection<?> c)
如果此collection包含指定collection中的所有元素,则返回true。
boolean isEmpty()
如果此collection不包含元素,则返回true。

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

public class Demo {
    public static void main(String[] args) {
        Collection collection=new ArrayList();
        collection.add(100);
        collection.add(200);
        collection.add(300);
        collection.add(400);
    
        boolean b1= collection.contains(100);

        Collection collection1=new ArrayList();
        collection1.add(100);
        collection1.add(200);
        boolean b2 = collection.containsAll(collection1);

        boolean b3 = collection.isEmpty();
        
        System.out.println(b1);
        System.out.println(b2);
        System.out.println(b3);
	}
}
/*
运行结果:
true
true
false
*/

遍历的方法:
通过迭代器遍历集合中的元素
Iterator接口:对collection进行迭代的迭代器。
返回Iterator的子类对象

我们可使用以下方法对集合进行遍历
boolean hasNext()
如果仍有元素可以迭代,则返回 true。
E next()
返回迭代的下一个元素。

int size()
返回此 collection 中的元素数。

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Demo {
    public static void main(String[] args) {
        Collection arrayList=new ArrayList();
        arrayList.add(100);
        arrayList.add(200);
        arrayList.add(300);
        arrayList.add(400);
        arrayList.add(500);
        arrayList.add(600);
       
		//输出iterator可得:java.util.ArrayList$Itr@1b6d3586。$代表该类是一个内部类,可以访问外部类成员
		//private class Itr implements Iterator<E>
        Iterator iterator=arrayList.iterator();       
        while (iterator.hasNext())
        {
            Object next = iterator.next();//将指针下移
            System.out.println(next);
        }

        int size = arrayList.size();
        System.out.println(size);
    }
}
/*
运行结果:
100
200
300
400
500
600
6
*/

boolean retainAll(Collection c)
仅保留此collection中那些也包含在指定collection的元素。换句话说,移除此collection中未包含在指定collection中的所有元素。

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

public class Demo {
    public static void main(String[] args) {
        Collection collection1=new ArrayList();
        collection1.add(100);
        collection1.add(200);
        collection1.add(300);
        collection1.add(400);
        Collection collection2=new ArrayList();
        collection2.add(300);
        collection2.add(400);
        collection2.add(500);
        collection2.add(600);

		//保留collection1和collection2中的交集元素
        boolean b = collection1.retainAll(collection2);
        System.out.println(b);
        System.out.println(collection1);
        System.out.println(collection2);
    }
}
/*
运行结果:
true
[300, 400]
[300, 400, 500, 600]
*/

Object[] toArray()
返回包含此collection中所有元素的数组。

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

public class Demo {
    public static void main(String[] args) {
        Collection collection=new ArrayList();
        collection.add(100);
        collection.add(200);
        collection.add(300);
        Object[] objects = collection.toArray();
        System.out.println(Arrays.toString(objects));
    }
}
/*
输出结果:
[100, 200, 300]
*/

List集合

有序的 collection(也称为序列)。列表通常允许重复的元素。

方法

void add(int index, E element)
在列表的指定位置插入指定元素(可选操作)。
int indexOf(Object o)
返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回-1。
int lastIndexOf(Object o)
返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回-1。
List subList(int fromIndex,int toIndex)
返回列表中指定的fromIndex(包括 )和toIndex(不包括)之间的部分视图。

import java.util.ArrayList;
import java.util.List;

public class Demo {
    public static void main(String[] args) {
        List list=new ArrayList();
        list.add(100);
        list.add(0,200);
        list.add(1,300);
        list.add(100);
        System.out.println(list);

        int index1= list.indexOf(100);
        int index2 = list.lastIndexOf(100);
        System.out.println(index1);
        System.out.println(index2);

        List list1 = list.subList(0, 3);
        System.out.println(list);
        System.out.println(list1);

		
    }
}
/*
运行结果:
[200, 300, 100, 100]
2
3
[200, 300, 100, 100]
[200, 300, 100]
*/

E get(int index)
返回列表中指定位置的元素。
E set(int index,E element)
用指定元素替换列表中指定位置的元素(可选操作)。

import java.util.ArrayList;
import java.util.List;

public class Demo {
    public static void main(String[] args) {
        List list=new ArrayList();
        list.add(100);
        list.add(200);
        list.add(300);
        list.add(400);
        Object o1 = list.get(1);
        System.out.println(o1);

        //返回被替换的旧元素
        Object o2 = list.set(0, 10);
        System.out.println(o2);
        System.out.println(list);
    }
}
/*
运行结果:
200
100
[10, 200, 300, 400]
*/

List集合遍历的三种方式

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

public class Demo {
    public static void main(String[] args) {
        List list=new ArrayList();
        list.add(100);
        list.add(200);
        list.add(300);
        list.add(400);
        //遍历List集合
        //方式1:通过迭代器
        Iterator iterator = list.iterator();
        while (iterator.hasNext())
        {
            Object next = iterator.next();
            System.out.println(next);
        }
        System.out.println("-------------");
        //方法2:在for循环中使用get方法
        //因为Collection接口中没有get方法,所以无法用for循环遍历集合
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        System.out.println("-------------");
        //方式3:List集合本身具有的迭代器ListIterator
        ListIterator listIterator = list.listIterator();
        while (listIterator.hasNext())
        {
            Object next = listIterator.next();
            System.out.println(next);
        }

    }
}
/*
运行结果:
100
200
300
400
-------------
100
200
300
400
-------------
100
200
300
400
*/

正向迭代和反向迭代

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class Demo {
    public static void main(String[] args) {
        List list=new ArrayList();
        list.add(1001);
        list.add(1002);
        list.add(1003);
        list.add(1004);
        list.add(1005);
        //正向迭代
        ListIterator listIterator = list.listIterator();
        while (listIterator.hasNext())
        {
            Object next = listIterator.next();
            System.out.println(next);
        }
        //反向迭代
        //注意反向迭代前要先进行正向迭代。即先将指针移至集合的最后一位,才能进行反向迭代
        System.out.println("---------");
        while (listIterator.hasPrevious())	//判断有没有上一个元素
        {
            Object previous = listIterator.previous();	//获取上一个元素并使指针上移
            System.out.println(previous);
        }
    }
}
并发修改异常
public class Demo {
    public static void main(String[] args) {
        //有一个集合,判断里面有没有 "world" 这个元素,如果有,就添加一个 "javaee" 元素,请写代码实现。
        List list=new ArrayList();
        list.add("aa");
        list.add("bb");
        list.add("world");
        list.add("cc");
        ListIterator listIterator = list.listIterator();
        while (listIterator.hasNext())
        {
            Object next = listIterator.next();
            String str=(String)next;
            if(str.equals("world"))
                list.add("javaee");
        }
    }
}
/*
运行后会产生异常:Exception in thread "main" java.util.ConcurrentModificationException(并发修改异常)
*/

我们来简单探讨一下异常产生的原因
在ListItr这个内部类中,有两个成员变量:
expectedModCount:表示对ArrayList修改次数的期望值,它的初始值为modCount。
modCount:是AbstractList类中的一个成员变量
每次进行调用add或remove方法时,modCount的值会发生变化。
我们再来看next方法,next方法中调用了checkForComodification方法,我们可以看一下这个方法的代码:

 final void checkForComodification() {
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
    }

也就是说在调用next方法时,如果modCount != expectedModCount就会抛出ConcurrentModificationException这个异常,即并发修改异常。
总结一下就是在add或remove方法会使modCount的值发生改变,致使在调用next方法时modCount与expectedModCount不相等所以产生了并发修改异常 。

解决方法:

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class Demo {
    public static void main(String[] args) {
        //方式1:使用迭代器自带的添加和删除方法
        List list=new ArrayList();
        list.add("aa");
        list.add("bb");
        list.add("world");
        list.add("cc");
        ListIterator listIterator = list.listIterator();
        while (listIterator.hasNext()) {
            Object next = listIterator.next();
            String str = (String) next;
            if (str.equals("world"))
                listIterator.add("javaee");
        }
    }
}
import java.util.ArrayList;
import java.util.List;

public class Demo {
    public static void main(String[] args) {
        //方式2:使用for循环
        List list=new ArrayList();
        list.add("aa");
        list.add("bb");
        list.add("world");
        list.add("cc");
        for (int i = 0; i < list.size(); i++) {
            Object o = list.get(i);
            String str=(String)o;
            if (str.equals("world"))
                list.add("javaee");
        }
    }
}
ArrayList类、Vector类、LinkedList类

ArrayList类:List接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括null在内的所有元素。除了实现List接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。
Vector类:Vector类可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件。
LinkedList类:List 接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素(包括 null)。除了实现 List 接口外,LinkedList 类还为在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。这些操作允许将链接列表用作堆栈、队列或双端队列。

三个子类的比较:
ArrayList:底层数据结构是数组,查询快,增删慢。线程不安全,效率高。
Vector:底层数据结构是数组,查询快,增删慢。线程安全,效率低。
LinkedList:底层数据结构是链表,查询慢,增删快。线程不安全,效率高。

三个子类的特殊方法
除了可以用迭代器和for循环遍历ArrayList集合,还可以使用forEach方法
public void forEach(Consumer<? super E> action)
对Iterable的每个元素执行给定的操作,直到所有元素都被处理或动作引发异常。
对于这个方法需要传入一个Consumer类的对象,经查询该类为一个接口。所以传入该接口子类的对象

//方法1:创建该接口的子类,然后传入该类对象
import java.util.ArrayList;
import java.util.function.Consumer;

public class Demo {
    public static void main(String[] args) {
        ArrayList arrayList=new ArrayList();
        arrayList.add("aaa");
        arrayList.add("bbb");
        arrayList.add("ccc");
        arrayList.add("aaa");
        arrayList.add("ddd");
        arrayList.add("eee");
        arrayList.forEach(new MyConsumer());
    }
}
class MyConsumer implements Consumer<String>
{
	//在该方法中对传入的对象,即集合中的元素进行操作
    @Override
    public void accept(String s) {
        System.out.println(s);
    }
}
//方法2:创建匿名内部类,在匿名内部类中重写accept方法
import java.util.ArrayList;
import java.util.function.Consumer;

public class Demo1 {
    public static void main(String[] args) {
        ArrayList arrayList=new ArrayList();
        arrayList.add("aaa");
        arrayList.add("bbb");
        arrayList.add("ccc");
        arrayList.add("aaa");
        arrayList.add("ddd");
        arrayList.add("eee");
        arrayList.forEach(new Consumer() {
            @Override
            public void accept(Object o) {
                System.out.println(o);
            }
        });
    }
}

Vector类特有的迭代器
使用方法和iterator方法和listIterator方法类似

import java.util.Enumeration;
import java.util.Vector;

public class Demo {
    public static void main(String[] args) {
        //Vector自带的迭代器
        Vector vector = new Vector();
        vector.add(100);
        vector.add(200);
        vector.add(300);
        Enumeration elements = vector.elements();
        while (elements.hasMoreElements())
        {
            Object o = elements.nextElement();
            System.out.println(o);
        }
    }
}

LinkedList类中一些特有方法
public E peek()
获取但不移除此列表的头(第一个元素)。
public E poll()
获取并移除此列表的头(第一个元素)
public E pop()
从此列表所表示的堆栈处弹出一个元素。换句话说,移除并返回此列表的第一个元素。

import java.util.LinkedList;

public class Demo2 {
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();
        linkedList.add(100);
        linkedList.add(200);
        linkedList.add(300);

        Object peek = linkedList.peek();
        System.out.println(peek);
        Object poll = linkedList.poll();
        System.out.println(poll);
        System.out.println(linkedList);
        Object pop = linkedList.pop();
        System.out.println(pop);
        System.out.println(linkedList);
    }
}
/*
运行结果:
100
100
[200, 300]
200
[300]
*/

poll方法和pop方法的区别
poll是队列数据结构实现类的方法,从队首获取元素,同时获取的这个元素将从原队列删除;当队列中没有元素时,调用方法输出返回的元素会输出null
pop是栈结构的实现类的方法,表示返回栈顶的元素,同时该元素从栈中删除,当栈中没有元素时,调用该方法会发生异常

import java.util.LinkedList;

public class Demo {
    public static void main(String[] args) {     
        LinkedList linkedList = new LinkedList();
        linkedList.add(100);
        linkedList.add(200);
        linkedList.add(300);
        
        linkedList.clear();
        Object poll1 = linkedList.poll();
        //调用pop方法会出现异常
        //Exception in thread "main" java.util.NoSuchElementException
        Object pop1 = linkedList.pop();
        System.out.println(poll1);	//此处会输出null
    }
}
发布了26 篇原创文章 · 获赞 1 · 访问量 344

猜你喜欢

转载自blog.csdn.net/weixin_45919908/article/details/103963288