java-Collection集合,List集合

集合数组

java-Collection集合,List集合_第1张图片

65.集合的由来和集合继承体系图

-集合的由来:数组长度是固定,当添加的元素超过了数组的长度时需要对数组重新定义,太麻烦,java内部给我们提供了集合类,能存储任意对象,长度是可以改变的,随着元素的增加而增加,随着元素的减少而减少 

-数组和集合的区别:

   1:

           *数组既可以存储基本数据类型,也可以存储引用数据类型,基本数据类型存储的是值,引用数据类型存储的是地址值

           *集合只能存储引用数据类型(对象)集合中也可以存储基本数据类型,但在存储的时候会自动装箱为对象,100->new Integer(100)

    2:

            *数组的长度是固定的,不能自动增长

            *集合的长度是可变的,可以根据元素的增加而增长

-集合和数组什么时候用:

            *如果元素个数是固定推荐用数组,因为当使用集合时,由于集合也有通过数组实现的,所以在赋值时可能会产生大量垃圾,浪费内存

            *如果元素个数不是固定的推荐用集合

-集合继承体系图:

java-Collection集合,List集合_第2张图片

66.Collection集合的基本功能

-方法:

        boolean add(E e)              //向集合中添加元素(参数为object的任意对象)

注:add方法如果是List集合一直会返回true,因为List集合是可以存储重复元素的,如果是Set集合存储重复元素就会返回false
        boolean remove(Object o)      //删除集合中的元素
        void clear()                               //清空集合中的元素
        boolean contains(Object o)    //查看集合中是否包含指定元素,返回一个boolean值
        boolean isEmpty()                   //判断集合是否为空
        int size()                                    //获取集合中元素的个数

-ArrayList的父类的父类重写toString方法,所以在打印对象引用的时候,输出的结果不是Object类中toString的结果

package Collection;

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

public class demo1 {

	public static void main(String[] args) {
		Collection c = new ArrayList();           //父类引用指向子类对象,编译看父类,运行看子类
		
		boolean b1 = c.add("abc");  
		boolean b2 = c.add(true);                 //基本数据类型,会自动装箱,new Boolean(true);
		boolean b3 = c.add(123);                 //new Integer(123)
		boolean b4 = c.add(new Student("张三",23));     
		
		System.out.println(c);
	}

}

67.集合的遍历

-遍历:其实就是依次获取集合中的每一个元素

-实现:将集合转换为数组,可以实现集合的遍历

           方法:toArray();                   //将集合转换为数组

package Collection;

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

public class demo2 {

	public static void main(String[] args) {
		demo1();
		Collection c = new ArrayList();
		c.add(new Student("张三",23));         //Object obj = new Student("张三",23);  向上转型 ,多态弊端无法使用子类特有的属性和方法
		c.add(new Student("李四",24));
		c.add(new Student("王五",25));
		c.add(new Student("赵六",26));
		Object[] arr = c.toArray();                  //将集合转换为Object数组
		for (int i = 0; i < arr.length; i++) {
			//System.out.println(arr[i]);        //它的作用只是为了显示
			Student s = (Student)arr[i];          //将obj向下转型为Student对象,这样就可以使用student中特有的属性和方法
			System.out.println(s.getName()+".."+s.getAge());    //这样不仅可以显示,还可以获取数据做其他操作
		}
	}

	private static void demo1() {
		Collection c = new ArrayList();
		c.add("a");
		c.add("b");
		c.add("c");
		c.add("d");
		
		Object[] arr = c.toArray();
		for (int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]);
		}
	}

}

java-Collection集合,List集合_第3张图片

68.Collection集合中带All的方法测试

-方法:

        boolean addAll(Collection c)                          //将整个集合添加为另一集合的元素中,合并
        boolean removeAll(Collection c)                    //删除的是交集
        boolean containsAll(Collection c)                  //判断一集合是否包含另一集合的元素,可以重复,但如果另一集合含有集合中不存在的元素,则返回fasle
        boolean retainAll(Collection c)                       //获取两个集合的交集,如果调用的集合改变就返回true,如果调用的集合不变就返回false

package Collection;

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

public class demo3 {

	public static void main(String[] args) {
		addAll();
		removeAll();
		containsAll();
		Collection c1 = new ArrayList();
		c1.add("a");
		c1.add("b");
		c1.add("c");
		c1.add("d");
		Collection c2 = new ArrayList();
		c2.add("a");
		c2.add("b");
		c2.add("b");
		boolean b = c1.retainAll(c2);
		Collection c3 = new ArrayList();
		c3.add("a");
		c3.add("b");
		c3.add("c");
		c3.add("d");
		c3.add("e");
		c3.add("f");
		System.out.println("获取c1,c2中相同的元素,若c1改变,返回true若不变,返回false");
		System.out.println(b);
		System.out.println(c1);
		System.out.println("c3包含c1的全部元素,此时c1不变,返回false");
		boolean b2 = c1.retainAll(c3);
		System.out.println(b2);
		System.out.println(c1);
	}

	private static void containsAll() {
		Collection c1 = new ArrayList();
		c1.add("a");
		c1.add("b");
		c1.add("c");
		c1.add("d");
		Collection c2 = new ArrayList();
		c2.add("a");
		c2.add("b");
		c2.add("b");
		boolean b = c1.containsAll(c2);
		System.out.println("判断c1中是否含有c2中的所有元素,c2中的元素可以重复,但如果含有c1没有的元素,则返回false");
		System.out.println(b);
		System.out.println(c1);
	}

	private static void removeAll() {
		Collection c1 = new ArrayList();
		c1.add("a");
		c1.add("b");
		c1.add("c");
		c1.add("d");
		Collection c2 = new ArrayList();
		c2.add("a");
		c2.add("b");
		c2.add("3");
		boolean b = c1.removeAll(c2);
		System.out.println("获取两个集合的交集,若没有交集则返回false");
		System.out.println(b);
		System.out.println(c1);
	}

	private static void addAll() {
		Collection c1 = new ArrayList();
		c1.add("a");
		c1.add("b");
		c1.add("c");
		c1.add("d");
		Collection c2 = new ArrayList();
		c2.add("a");
		c2.add("b");
		c2.add("3");
		boolean b = c1.addAll(c2);
		System.out.println("将两个集合合并,并将结果返回给调用的集合");
		System.out.println(b);
		System.out.println(c1);
	}

}

java-Collection集合,List集合_第4张图片

69.集合的遍历之迭代器遍历

-概述: 集合是用来存储元素,存储的元素需要查看,那么就需要迭代(遍历) 

-迭代器:Iterator(接口)

-迭代器原理:迭代器是对集合进行遍历,而每一个集合内部的存储结构都是不同的,所以每一个集合存和取都是不一样,那么就需要在每一个类中定义hasNext()和next()方法,这样做是可以的,但是会让整个集合体系过于臃肿,迭代器是将这样的方法向上抽取出接口,然后在每个类的内部,定义自己迭代方式,这样做的好处有二,第一规定了整个集合体系的遍历方式都是hasNext()和next()方法,第二,代码有底层内部实现,使用者不用管怎么实现的,会用即可 

-方法:

          *boolean hasnext()                    //如果仍有元素可以迭代,返回true

          *next()                                         //返回迭代的下一个元素

         

package Collection;

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

public class demo4 {

	public static void main(String[] args) {
		demo1();
		Collection c = new ArrayList();
		c.add(new Student("张三",23));         //Object obj = new Student("张三",23);  向上转型 ,多态弊端无法使用子类特有的属性和方法
		c.add(new Student("李四",24));
		c.add(new Student("王五",25));
		c.add(new Student("赵六",26));
		Iterator it = c.iterator();           //获取迭代器
		while(it.hasNext()){
			Student s = (Student)it.next();                  //将集合中的元素向下转型,由object对象转换为Student对象
			System.out.println(s.getName()+".."+s.getAge());
		}
	}

	private static void demo1() {
		Collection c = new ArrayList();
		c.add("a");
		c.add("b");
		c.add("c");
		c.add("d");
		Iterator it = c.iterator();          //获取迭代器
		while(it.hasNext()){
			System.out.println(it.next());           //指针会自动向后移动
 		}
	}

}

java-Collection集合,List集合_第5张图片

70.List集合的特有功能概述

-概述:有序的Collection也称为序列,此接口的用户可以对列表中每个元素的插入位置进行精确的控制,用户可以根据元素的整数索引访问元素,并搜索列表中的元素。

-方法:

    * void add(int index,E element)        //在列表的指定位置插入元素
    * E remove(int index)                        //删除指定位置的元素
    * E get(int index)                               //根据索引获取指定元素
    * E set(int index,E element)             //修改指定位置的元素

package Collection;

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

public class demo5_List {

	public static void main(String[] args) {
		add();
		remove();
		get();
		set();
	}

	private static void set() {
		List list = new ArrayList();
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("d");
		list.set(1, "x");
		System.out.println(list);
	}

	private static void get() {
		List list = new ArrayList();
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("d");
		//利用迭代器遍历List集合
		Iterator it = list.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}	
		//通过索引遍历List集合
		for(int i=0;i=0都不会触发异常
		//list.add(10,"e");               IndexOutOfBoundsException索引越界异常
		System.out.println(list);
	}

}

java-Collection集合,List集合_第6张图片

-List集合的遍历

package Collection;

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

public class demo6 {

	public static void main(String[] args) {
		List list  = new ArrayList();
		list.add(new Student("张三",23));
		list.add(new Student("李四",24));
		list.add(new Student("王五",25));
		list.add(new Student("赵六",26));
		//利用get方法遍历
		for (int i = 0; i < list.size(); i++) {
			//System.out.println(list.get(i));
			Student s = (Student)list.get(i);
			System.out.println(s.getName()+".."+s.getAge());
		}
		System.out.println();
		//利用迭代器遍历
		Iterator it = list.iterator();
		while(it.hasNext()){
			Student s = (Student)it.next();             //将obj对象向下转型,这样就可以使用student类中特有的属性和方法
			System.out.println(s.getName()+".."+s.getAge());
		}
	}

}

-并发修改异常产生的原因及解决方案

-ListIterator接口:系列表迭代器,允许按任一方法遍历集合,迭代期间修改列表,接口中有add方法,可以在迭代期间向列表添加元素,而不触发并发修改异常(ConcurrentModificationException)的错误

package Collection;

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

public class demo7_listIterator {
	public static void main(String[] args){
		List list = new ArrayList();
		list.add("a");
		list.add("b");
		list.add("hello");
		list.add("c");
		list.add("d");
		/*Iterator it= list.iterator();     //获取迭代器
		while (it.hasNext()) {             //判断集合是否有元素
			String s = (String)it.next();      //向下转型
			if("hello".equals(s)){             //如果集合中含有"hello"字符串,就向集合中添加world
				list.add("wolrd");          //遍历的同时再增加元素,不允许在遍历期间修改集合,触发ConcurrentModificationException异常(并发修改异常)
			}
		}*/
		ListIterator lit = list.listIterator();
		while (lit.hasNext()) {             //判断集合是否有元素
			String s = (String)lit.next();      //向下转型
			if("hello".equals(s)){             //如果集合中含有"hello"字符串,就向集合中添加world
				lit.add("wolrd");               //调用	ListIterator接口中的add方法,允许再遍历期间修改集合
			}
		}
		System.out.println(list);
	}
}

-ListIterator接口功能

      * boolean hasNext()         是否有下一个
      * boolean hasPrevious()  是否有前一个
      * Object next()                  返回下一个元素
      * Object previous()           返回上一个元素

71.Vector接口的概述

-概述:实现了List接口,功能被ArrayList取代

-特有功能:

未实现List接口时,Vector通过枚举来遍历获取集合中的值

          *void addElement(obj E)           添加元素

-Enumeration      枚举对象,实现枚举功能

       *hasMoreElements()             测试此枚举是否包含更多的元素

       *nextElement()                      如果还有下一个对象,返回下一个元素

package Collection;

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

public class demo8_Vector {

	public static void main(String[] args) {
		Vector v = new Vector();
		v.addElement("a");
		v.addElement("b");
		v.addElement("c");
		v.addElement("d");
		Enumeration en = v.elements();                 //获取枚举
		while(en.hasMoreElements()){                 //判断是否有元素
			System.out.println(en.nextElement());      //输出集合中的所有元素
		}
	}

}

 72.List的三个子类

-数组与链表的比较:
    数组:查询快修改也快

               增加和删除慢

    链表:查询慢修改也慢

               增加和删除快

-ArrayList,LinkList,Vector的比较:

        *ArrayList:
              底层数据结构是数组,查询快,增删慢。
              线程不安全,效率高。
        *Vector:
              底层数据结构是数组,查询快,增删慢。
              线程安全,效率低。
                 *1.Vector相对ArrayList查询慢(线程安全的)
                 *2.Vector相对LinkedList增删慢(数组结构)
        *LinkedList:
              底层数据结构是链表,查询慢,增删快
              线程不安全,效率高
   *Vector和ArrayList的区别:
              Vector是线程安全的,效率低
              ArrayList是线程不安全的,效率高
        共同点:都是数组实现的
    *ArrayList和LinkedList的区别
              ArrayList底层是数组结果,查询和修改快
              LinkedList底层是链表结构的,增和删比较快,查询和修改比较慢
       共同点:都是线程不安全的

73.ArrayList去重

-思路:1.创建新集合接收老集合中不重复的值

            2.获取老集合中的迭代器

            3.遍历老集合

            4.通过新集合是否包含老集合中的元素,如果包含就不添加,不包含就添加

package Collection;

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

public class demo9_ArrayList去重 {

	public static void main(String[] args) {
		ArrayList list = new ArrayList();
		list.add("a");
		list.add("a");
		list.add("a");
		list.add("b");
		list.add("b");
		list.add("b");
		list.add("c");
		list.add("c");
		list.add("b");
		ArrayList li = method(list);
		System.out.println(li);
	}
	public static ArrayList method(ArrayList list){
		ArrayList al = new ArrayList();                     //创建新集合
		Iterator it = list.iterator();                            //获取传入集合的迭代器
		while(it.hasNext()){
			Object obj = it.next();                                //取得集合中每一个元素
			if(!al.contains(obj)){                                  //如果新集合不包含obj,就添加
				al.add(obj);
			}
		}
		return al;
	}
}

-自定义类实现去重

-注意点:Contains方法和remove方法底层是通过equals方法实现的,如果自定义类没有重写equals方法的话,就会调用object类的equals方法,此时比较的是对象的地址值。

package Collection;

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

public class demo9_ArrayLIst2 {

	public static void main(String[] args) {
		ArrayList list = new ArrayList();
		list.add(new Student("张三",23));
		list.add(new Student("张三",23));
		list.add(new Student("张三",25));
		list.add(new Student("李四",24));
		list.add(new Student("李四",24));
		ArrayList al = method(list);
		System.out.println(al);
	}
	public static ArrayList method(ArrayList list){
		ArrayList aList = new ArrayList();                //创建新集合
		Iterator it = list.iterator();
		while(it.hasNext()){
			Object obj = it.next();
			if(!aList.contains(obj)){                            //Contains底层是通过equals实现的,如果自定义类没有重写equals方法,就会自动调用object类的equals方法,此时比较的是地址值
				aList.add(obj);
			}
		}
		return aList;
	}
}


Student类:
@Override           //重写equals方法
	public boolean equals(Object obj) {
		Student s = (Student)obj;
		return this.name.equals(s.name) && this.age == s.age;
	}

75.LinkedList的概述及使用

-概述:List接口的链表形式实现

-链表:查询和修改慢,增加和删除快,因为链表的每一个元素(除开头和结尾外)都保留着它前一个元素和后一个元素的地址,这样就可以以链的形式连接,但查询时,只能从头或从尾依次查找,直至找到,所以查询慢,而删除时只要将两个元素之间的链去掉即可。

-方法:

    * public void addFirst(E e)及addLast(E e)           //在链的头部或尾部添加元素
    * public E getFirst()及getLast()                             //获取链的头部或尾部的元素
    * public E removeFirst()及public E removeLast()       //删除链的头部或尾部的元素
    * public E get(int index)             //获取指定索引的元素,由(index和size/2)比较,判断应从头部还是尾部开始查找

-用LinkedList模拟栈数据结构

package Collection;

import java.util.LinkedList;

public class demo11_stack {
	private LinkedList list = new LinkedList();
	
	public static void main(String[] args) {
		demo11_stack d = new demo11_stack();
		d.inStack("a");
		d.inStack("b");
		d.inStack("c");
		d.inStack("d");
		while(!d.isEmpty()){
			System.out.println(d.outStack());
		}
	}
	public void inStack(Object obj){
		 list.addFirst(obj);
	}
	public Object outStack(){
		return list.removeFirst();
	}
	public boolean isEmpty(){
		return list.isEmpty();
	}
}

77.增强for概述及其使用

-概述:简化数组及Collection集合的遍历(底层用迭代器实现)

-格式:

           for(元素数据类型 变量 : 数组或者Collection集合) {
                  使用变量即可,该变量就是元素
            }

package generic;

import java.util.ArrayList;

public class demo5_foreach {

	public static void main(String[] args) {
		int arr[]  = {11,22,33,44,55};
		for (int i : arr) {
			System.out.println(i);
		}
		ArrayList< String > list = new ArrayList<>();
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("d");
		for (String string : list) {
			System.out.println(string);
		}
	}

}

78.三种迭代的能否删除

package generic;

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

public class demo6 {

	public static void main(String[] args) {
		ArrayList list = new ArrayList<>();
		list.add("a");
		list.add("b");
		list.add("b");
		list.add("c");
		list.add("d");
		//for 循环遍历删除指定元素
		/*for (int i = 0; i < list.size(); i++) {       
			if("b".equals(list.get(i))){            //找到"b"
				list.remove(i--);                          //删除"b",并使索引回退一位,因为当删除一个元素时,list的size会减少一位,此时如果i的索引不减一的话,就会跳过删去元素的下一位元素
			}*/
		//迭代器循环遍历删除指定元素
		/*Iterator it = list.iterator();
		while (it.hasNext()) {
			if("b".equals(it.next())){
				it.remove();
				//list.remove("b");                不能用集合的修改方法,因为会出现并发修改异常
		}
		}*/
		//foreach循环遍历删除(不可以)因为foreach底层依赖迭代器实现
		/*for (String string : list) {
			if("b".equals(string)){
				list.remove("b");                //并发修改异常,不能删除指定元素
			}
		}*/
	}
}

79.静态导入

-概述:静态导入类方法

-格式:import static 包名... 类名.方法名

            可以直接导入到方法的级别

-注意事项:方法必须是静态的,但如果有多个同名的静态方法,容易不知道使用谁?这个时候要使用,必须加前缀。

80.可变参数

-概述:当定义方法的时候不知道应该定义多少个参数

-格式:

       *修饰符 返回值类型 方法名(数据类型 ... 变量名){}

-注意事项:

        *这里的可变参数其实是一个数组

        *如果一个方法有可变参数,并且还有多个参数,可变参数肯定是最后一个

package generic;

public class demo7_changeableargs {

	public static void main(String[] args) {
		String[] arr = {"a","b","c","d"};
		method("s1","z","x","y");
	}
	public static void method(String s1,String ... arr1){
		for (String string : arr1) {
			System.out.println(string);
		}
	}
}

81.asList方法

-功能:将数组转换成集合

-注意:

          *数组转换成集合后不能增加或删除元素,但是可以用集合的思想来操作数组,也就是说可以使用其他集合里的方法

          *基本数据类型转数组,会将整个数组转化为一个对象

          *将数组转化为集合,数组必须是引用数据类型

package Arrays;

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

public class demo2_asList {

	public static void main(String[] args) {
		Integer[] arr = {11,11,22,33,33,44,44,55};
		List list = Arrays.asList(arr);
		System.out.println(list);               //数组转集合只能是引用数据类型
		listtoarray();
	}

	private static void listtoarray() {
		ArrayList list = new ArrayList<>();
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("d");
		String[] arr = list.toArray(new String[5]); //当集合转数组时,数组的长度如果<=size,转换后的数组长度等于集合的size,如果>size,那么数组的长度就和你指定的长度一样
		for (String string : arr) {
			System.out.println(string);
		}
	}
}

82.集合中嵌套集合

package Collection;

import java.util.ArrayList;

public class demo12 {

	public static void main(String[] args) {
		ArrayList> list = new ArrayList<>();
		ArrayList First = new ArrayList<>();
		First.add(new Student("张三",23));
		First.add(new Student("李四",24));
		First.add(new Student("王五",25));
		ArrayList Second = new ArrayList<>();
		Second.add(new Student("赵六",26));
		Second.add(new Student("周七",27));
		Second.add(new Student("潘八",28));
		list.add(First);
		list.add(Second);
		for (ArrayList as :list ) {
			System.out.println(as);
			for (Student s : as) {
				System.out.println(s);
			}
		}
 	}

}

你可能感兴趣的:(java,集合)