[TOC]

Collection集合框架

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

集合原理:(重点)

  • 集合的底层部分采用数组方式,比如创建一个10个大小的数组,之后往里面填数组当填满之后,它又创建了一个比原数组1.5倍大的数组,把原数组的数据都拷贝到新数组中,原数组将成为垃圾被丢弃;(然后一直循环)


数组和集合的区别

  • 区别1 :
    • 数组既可以存储基本数据类型,又可以存储引用数据类型,基本数据类型存储的是值,引用数据类型存储的是地址值
    • 集合只能存储引用数据类型(对象)集合中也可以存储基本数据类型,但是在存储的时候会自动装箱变成对象
  • 区别2:
    • 数组长度是固定的,不能自动增长
    • 集合的长度的是可变的,可以根据元素的增加而增长


集合继承体系图:
Collection(单列集合的根接口)

  • List : 有序(存和取的顺序一致),有索引可以存储重复;
    • ArrayList 数组实现
    • LinkedList 链表实现
    • Vector (已被替换掉) 数组实现
  • Set : 无序()存和取的顺序补一致,无索引不可以存储重复;
    • HashSet 哈希算法
    • TreeSet 二叉数算法

WeiyiGeek.集合继承体系图

数组和集合什么时候用?

  • 1.如果元素个数是固定的推荐用数组;
  • 2.如果元素个数不是固定的推荐用集合;

注意事项:

  • collectionXxx.java使用了未经检查或不安全的操作.
  • 要了解详细信息,请使用 -Xlint:unchecked重新编译.java编译器认为该程序存在安全隐患温馨提示:这不是编译失败,所以先不用理会,等学了泛型你就知道了

基础语法:

java.util 

public interface Collection<E> //<E> 泛型 jdk1.5出现所以,注意接口不能直接new需要找到它的已知实现类;
extends Iterable<E> //扩展迭代器

#实例化常常采用集合继承体系进行实现
boolean add(E e) //#确保此集合包含指定的元素(可选操作)。
boolean remove(Object o) //#从这个集合中移除指定元素的一个实例,如果它是存在的(可选操作)。
int size() //#返回此集合中的元素的数目。
boolean contains(Object o) //#返回 true如果集合包含指定元素。
boolean isEmpty() // #返回 true如果集合不包含任何元素。
void clear() //#从这个集合中移除所有的元素(可选操作)。


集合继承ArrayList

基础实例:
需求:我有5个学生,请把这个5个学生的信息存储到数组中,并遍历数组,获取得到每一个学生信息。

package com.weiyi.Collection;
//创建一个学生类
public class Students {
4private String name;
4private int age;
4//创建空参和有参
4public Students() {
4}
4public Students(String name, int age) {
44this.name = name;
44this.age = age;
4}
4
4//创建get/setter 方法
4public String getName() {
44return name;
4}
4public void setName(String name) {
44this.name = name;
4}
4public int getAge() {
44return age;
4}
4public void setAge(int age) {
44this.age = age;
4}
}

案例需要上面的学生类

package com.weiyigeek.Collection;
import java.util.ArrayList;
import java.util.Collection;

import com.weiyi.Collection.Students; //引入学生类

public class Demo1_Collection {
4/**
* Student[] arr = new Student[5]; //存储学生对象
arr[0] = new Student("张三", 23);
arr[1] = new Student("李四", 24);
arr[2] = new Student("王五", 25);
arr[3] = new Student("赵六", 26);
arr[4] = new Student("马哥", 20);
*
*/
4public static void main(String[] args) {
44//示例1.基本数据类型数组
44//int[] arr = new int[5];
44
44//示例2.引用数据类型数组
44Students[] arrs = new Students[5];
44arrs[0] = new Students("张三", 23);
44arrs[1] = new Students("李四", 25);
44arrs[2] = new Students("王五", 27);
44
44for (int i = 0; i < arrs.length; i++) {
444System.out.println(arrs[i]); //数组和集合引用数据类型存储都是地址值
44}
44
44//示例3.Collection类的使用 (编译看父类,运行看子类)
44Collection c = new ArrayList(); //父类引用指向子类对象
44//add方法如果是List集合一直都返回True,因为List集合中是可以存储重复元素的;但如果是set集合当存储重复元素的时候就会返回false;
44boolean b1 = c.add("abc");
44boolean b2 = c.add(true); //自动装箱特性new Boolean(true)
44boolean b3 = c.add(100);
44boolean b4 = c.add(10.24);
44boolean b5 = c.add(new Students("张三",23));
44boolean b6 = c.add("abc"); //可以添加重复的元素
44System.out.println(c); //类似于Python中的集合
44//ArrayList 的父类的父类重写toString方法,所以在打印对象的引用的时候输出的结果不是Object类中的toString方法
44System.out.println(c.toString()); //类似于Python中的集合

44//示例4.其他的方法
44System.out.println("集合元素个数 :" + c.size());//获取集合中元素个数

44c.remove("abc"); //删除元素
44System.out.println("删除指定元素 : "+c); //类似于Python中的集合

44System.out.println("判断是否包含 " + c.contains(10.24));
4
44c.clear();//清空元素
44System.out.println("清空元素 : " + c); //类似于Python中的集合
44
44System.out.println("判断是否为空 : " + c.isEmpty()); //判断集合是否为空
4}
}

执行结果:

[email protected]15db9742
[email protected]6d06d69c
[email protected]7852e922
null
null

[abc, true, 100, 10.24, [email protected]4e25154f, abc]
[abc, true, 100, 10.24, [email protected]4e25154f, abc]

集合元素个数 :6
删除指定元素 : [true, 100, 10.24, [email protected]4e25154f, abc]
判断是否包含 true
清空元素 : []
判断是否为空 : true

Tips : 数组和集合存储引用数据类型存的都是地址值
WeiyiGeek.


集合转数组遍历:
描述:集合常用方法

Object[] toArray()  //#返回包含此集合中所有元素的数组。 
boolean addAll(Collection c) //#将指定集合中的所有元素添加到这个集合(可选操作)。
boolean removeAll(Collection c) //#删除此集合中包含的所有元素(可选操作)的所有元素(可选操作)。
boolean containsAll(Collection c) //#返回 true如果这个集合包含指定集合的所有元素。
boolean retainAll(Collection c) //#仅保留包含在指定集合中的这个集合中的元素(可选操作)。 交集

基础示例:

package com.weiyigeek.Collection;
import java.util.ArrayList;
import java.util.Collection;

import com.weiyi.Collection.Students;

public class Demo2_Collection {

4public static void main(String[] args) {
44//示例1:集合遍历之集合转数组遍历
44Collection c = new ArrayList();
44c.add("a");
44c.add("b");
44c.add("c");
44c.add("d");
44Object[] arr = c.toArray(); //集合之数组遍历
44for (int i = 0; i < arr.length; i++) {
444System.out.print(arr[i] + " ");
44}
44
44
44System.out.println("\n##########分割线上##########");
44//示例2.集合转换成为数组
44Collection c1 = new ArrayList();
44c1.add(new Students("赵老师",24));
44c1.add(new Students("经老师",23));
44c1.add(new Students("渣渣辉",25));
44c1.add(new Students("刘师傅",26));
44Object[] arr1 = c1.toArray(); //将集合转换成数组
44for (int i = 0; i < arr1.length; i++) {
444Students s = (Students)arr1[i]; //向下转型
444System.out.println(s.getName() + " " + s.getAge()); //重点值得学习
44}
44
44
44//示例3.自带All()功能测试方法
44Collection c2 = new ArrayList();
44c2.add("a");
44c2.add("b");
44c2.add("c");
44c2.add("d");
44
44Collection c3 = new ArrayList();
44c3.add("1");
44c3.add("2");
44c3.add("3");
44c3.add("4");
44c3.add("a");

44System.out.println("##########分割线###########");
44c2.add(c3); //将c3看成一个对象添加到c1中 [1,2,3,4]
44System.out.println(c2);
44c2.addAll(c3); //将c3中的每一个元素添加到c1中
44System.out.println(c2);
44
44boolean b = c2.removeAll(c3); //将c2中的c3元素进行删除 (需要注意删除是交集)
44System.out.println("需要注意删除是交集");
44System.out.println(c2);
44
44boolean b1 = c2.containsAll(c3); //判断调用集合是否包含传入的集合
44System.out.println("c2是否包含c3 : " + b1);
44
44//取交集如果调用的集合改变就返回true(持续),否则返回false;
44boolean b2 = c2.retainAll(c3); //取交集
44System.out.println(b2);
44System.out.println(c2);
4}
}

执行结果:

a b c d 
##########分割线上##########
赵老师 24
经老师 23
渣渣辉 25
刘师傅 26
##########分割线###########
[a, b, c, d, [1, 2, 3, 4]]
[a, b, c, d, [1, 2, 3, 4], 1, 2, 3, 4]
需要注意删除是交集
[a, b, c, d, [1, 2, 3, 4]]
c2是否包含c3 : false
true
[]


集合之迭代器(Iterator)

描述:其实迭代都是遍历,而遍历也可以看做是迭代;迭代器概述集合是用来存储元素,存储的元素需要查看,那么就需要迭代(遍历);

迭代器原理:

  • 迭代器是对集合进行遍历,而每一个集合内部的存储结构都是不同的,所以每一个集合存和取都是不一样,那么就需要在每一个类中定义hasNext()和next()方法
  • 这样做是可以的,但是会让整个集合体系过于臃肿,迭代器是将这样的方法向上抽取出接口,然后在每个类的内部,定义自己迭代方式好处有二:
    • 第一规定了整个集合体系的遍历方式都是hasNext()和next()方法
    • 第二代码有底层内部实现,使用者不用管怎么实现的会用即可
#迭代器方法解析
java.util
public interface Iterator<E> #返回此集合中的元素的迭代器。
boolean hasNext() #返回 true如果迭代具有更多的元素。
E next() #返回迭代中的下一个元素。

迭代器源码解析

* 1,在eclipse中ctrl + shift + t找到ArrayList类
* 2,ctrl+o查找iterator()方法
* 3,查看返回值类型是new Itr(),说明Itr这个类实现Iterator接口
* 4,查找Itr这个内部类,发现重写了Iterator中的所有抽象方法
* 5,hasNext() 是判断集合中是否有参数,以及cursor标志位是否 == 集合的size个数
* 6,Next() 是集合进行迭代并输出迭代值

基础方法:

package com.weiyigeek.Collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import com.weiyi.Collection.Students;

@SuppressWarnings("rawtypes")

public class Demo3_Collection {
4@SuppressWarnings("unchecked")
4public static void main(String[] args) {
44//示例1.对集合中的元素进行迭代遍历
44Collection c = new ArrayList();
44c.add("Weiyi");
44c.add("Geek");
44c.add("1024");
44c.add("Java");
44Iterator it = c.iterator(); //获取迭代器
44boolean bl = it.hasNext(); //判断集合中是否有元素,有则返回true;
44Object obj = it.next(); //指针会记录当前位置向后移位;
44System.out.print(bl + " ");
44System.out.println(obj); //输入集合中第一个元素
44while(it.hasNext())
44{
444System.out.println(it.next());
44}
44

44//示例2.通过while循环来迭代集合数组
44Collection c1 = new ArrayList();
44c1.add(new Students("张伟", 15)); //父类引用指向子类对象
44c1.add(new Students("张杰", 29)); //Object obj = new Student
44c1.add(new Students("张根硕", 35));
44c1.add(new Students("大张伟", 25));
44Iterator it1 = c1.iterator();
44//Collection存储自定义对象并用迭代器遍历
44while(it1.hasNext())
44{
444Students s = (Students)it1.next(); //向下转型 强转
444System.out.println(s.getName() + " " + s.getAge());
44}
4}
}

执行结果:

true Weiyi
Geek
1024
Java

张伟 15
张杰 29
张根硕 35
大张伟 25


有序集合List

描述:List集合中不能有重复元素,否则返回false;List集合中才有索引,而set中是没有索引的
List集合的特有功能

* void add(int index,E element)
* E remove(int index)
* E get(int index)
* E set(int index,E element)

基础示例:

package com.weiyigeek.Collection;

import java.util.List;
import java.util.ArrayList;
import com.weiyi.Collection.Students;

public class Demo4_List {

4public static void main(String[] args) {
44//1.List集合功能(按照索引插入)
44List l = new ArrayList(); //注意是在java.util.List;
44l.add("Weiyi"); //object obj = new String();
44l.add("Geek");
44l.add("Love");
44l.add("Java");
44l.add(0,"Start"); //头部插入 INDEX <= SIZE 并且 Index >= 0 不会报索引异常
44l.add(5,"END"); //尾部插入
44System.out.println(l);
44
44//示例2.通过索引删除元素并且其返回
44Object demo1 = l.remove(3); //删除Love - 注意:删除的时候不会自动装箱
44System.out.println(l + " 删除的集合元素是 " + demo1);
44
44//示例3.根据索引获取元素
44Object demo2 = l.get(1);
44System.out.println("获取指定的索引的集合元素 :" + demo2 + l.get(2));
44//通过索引遍历List集合;
44for (int i = 0; i < l.size(); i++) {
444System.out.print(l.get(i) + " - ");
44}
44
44//示例4.根据索引进行指定位置元素进行修改
44l.set(3, "Editer");
44System.out.println("\n修改后的集合元素 : " + l);
44
44//综合实例
44//向List集合中存储学生对象然后通过size和get()方法结合遍历
44List list = new ArrayList();
44list.add(new Students("Weiyi",28));
44list.add(new Students("Geek",32));

44for (int i = 0; i < list.size(); i++) {
444//存储自定义对象通过size()和get()方式获取
444Students s = (Students)list.get(i); //向下引用
444System.out.println(i + " - " + s.getName() + " " + s.getAge());
44}
4}
}

执行结果:

[Start, Weiyi, Geek, Love, Java, END]
[Start, Weiyi, Geek, Java, END] 删除的集合元素是 Love
获取指定的索引的集合元素 :WeiyiGeek
Start - Weiyi - Geek - Java - END -
修改后的集合元素 : [Start, Weiyi, Geek, Editer, END]
0 - Weiyi 28
1 - Geek 32


集合继承Vector

描述:Vector是Java中的老员工了从jdk1.0但是现在已经被ArrayList所替代,Vector类实现了一个可增长对象数组,可以通过索引来访问元素,也可以根据需求来进行收缩对象数组;

#包
java.util.Vector<E>

#类
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable


#成员属性
protected int elementCount //#Vector对象的有效成分的数量。成分 elementData[0]通过 elementData[elementCount-1]是实际的项目

//#Vector类特有功能
* public void addElement(E obj) //添加元素
* public E elementAt(int index)
* public Enumeration elements()

//#迭代方式
public interface Enumeration<E> //一个实现枚举接口的对象生成一系列元素,一个在一个时间。连续调用方法返回的 nextElement连续单元系列。
boolean hasMoreElements() //#测试此枚举是否包含更多元素。
E nextElement() //#返回此枚举的下一个元素,如果此枚举对象至少有一个元素可以提供。

基础示例:

//示例1.Vector的迭代与添加元素
Vector v = new Vector();
v.addElement("Weiyi");
v.addElement("Geek");
v.addElement("Java");
Enumeration en = v.elements(); //获取枚举
while(en.hasMoreElements()) //判断集合中是否有元素
{
4//迭代获取集合中的元素
4System.out.print(en.nextElement() + " ");
}

//执行结果
Weiyi
Geek
Java


集合继承LinkedList

描述:双向链表实现的 List和 Deque接口。实现了所有的可选列表操作,并允许所有元素(包括 null)。
可以实现栈(先进后出)和堆(先进先出)的数据结构;
基础语法:

#包
java.util

#类结构
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, Serializable

#构造方法
LinkedList() #构造一个空列表。
LinkedList(Collection<? extends E> c) #构造一个包含指定集合的元素的列表,它们在集合的迭代器返回的顺序中返回。

#常用方法
* public void addFirst(E e)及addLast(E e)
* public E getFirst() 及 getLast()
* public E removeFirst() 及 public E removeLast()
* public E get(int index);

基础示例:

package com.weiyigeek.Collection;
import java.util.LinkedList;
public class Demo8_linkedList {
4public static void main(String[] args) {
44//示例1.集合常用方法展示
44LinkedList list = new LinkedList(); //创建Linked对象
44list.add("1");
44list.addFirst("0");
44list.addLast("2");
44
44System.out.println("获取集合中第一个元素:"+list.getFirst());
44System.out.println("获取集合中最后一个元素:"+list.getLast());
44System.out.println("返回删除的第一个元素:"+list.removeFirst());
44System.out.println("返回删除的最后一个元素:"+list.removeLast());
44System.out.println("利用索引获取元素 (原理值得学习): "+list.get(0));
4
44//示例2.采用LinkedList模拟栈结构
44LinkedStack stack = new LinkedStack();
44stack.in("a"); //进栈
44stack.in("b");
44stack.in("c");
44stack.in("d");
44//循环弹栈
44while(!stack.isEmpty()) {
444System.out.println(stack.out());
44}
44
44//示例3.实现堆即先进先出采用addFrist();以及RemoveFrist()即可
4}
}

//封装成为类
class LinkedStack {
4private LinkedList lt = new LinkedList();
4
4/**模拟栈先进先出**/
4public void in(Object obj) {
44lt.addLast(obj); //向末尾添加方法
4}
4public Object out() {
44return lt.removeLast(); //向末尾删除方法
4}
4
4//判断是否为空
4public boolean isEmpty() {
44return lt.isEmpty();
4}
}

执行结果:

获取集合中第一个元素:0
获取集合中最后一个元素:2
返回删除的第一个元素:0
返回删除的最后一个元素:2
利用索引获取元素 (原理值得学习): 1

d
c
b
a


List子类特点

描述:在说List子类特点的时候我们先说说数据结构之数组和链表_
数组与链表的区别?
A:数组:查询快修改也快,但是增删慢;
B:链表:查询慢修改也慢,但是增删快;

List的三个子类的特点?

  • ArrayList:
    • 底层数据结构是数组,查询快,增删慢。
    • 线程不安全,效率高
  • Vector:
    • 底层数据结构是数组,查询快,增删慢。
    • 线程安全,效率低
    • Vector相对ArrayList查询慢(线程安全的)
    • Vector相对LinkedList增删慢(数组结构)
  • LinkedList:
    • 底层数据结构是链表,查询慢,增删快。
    • 线程不安全,效率高

Vector和ArrayList的区别

  • Vector是线程安全的,效率低
  • ArrayList是线程不安全的,效率高
    共同点:都是数组实现的

ArrayList和LinkedList的区别

  • ArrayList底层是数组结果,查询和修改快
  • LinkedList底层是链表结构的,增和删比较快,查询和修改比较慢
    共同点:都是线程不安全的
  • List有三个儿子,我们到底使用谁呢?
    查询多用ArrayList
    增删多用LinkedList
    如果都多ArrayList


ArrayList示例

描述:前面我们已经简单的介绍了一些ArrayList集合的框架,下面直接演示集合参数过滤
基础示例:

package com.weiyigeek.Collection;

import java.util.ArrayList;
import java.util.Iterator;
import com.weiyi.Collection.Students; //重写了toString和equals方法

public class Demo7_ArrayList {
4public static void main(String[] args)
{
4/**
* A:案例演示
* 需求:ArrayList去除集合中字符串的重复值(字符串的内容相同)
* 思路:创建新集合方式
*/
44ArrayList newList = new ArrayList();
44newList.add("a");
44newList.add("c");
44newList.add("b");
44newList.add("b");
44newList.add("b");

44ArrayList list = getSingle(newList);
44System.out.println(list);
44
44/**
B:案例演示
* 需求:ArrayList去除集合中自定义对象元素的重复值(对象的成员变量值相同)
* **/
44ArrayList objList = new ArrayList();
44objList.add(new Students("张三",13)); //如果采用Object方式是对比的地址值是不一样的
44objList.add(new Students("张三",13));
44objList.add(new Students("张四",13));
44objList.add(new Students("王三",13));
44ArrayList objres = getSingleObj(objList); //循环方法进行对象去重
44objList.remove(new Students("张三",13)); //底层都是依赖于object的equals方法
44System.out.println(objres);
4}
4
4/*
* 参数: 去除重复
* 1,返回ArrayList类型类别
* 2,参数列表ArrayList
* 创建新集合、根据传入的集合获取迭代器
* 遍历老集合、通过新集合判断是否包含老集合中的元素,如果不包含就不添加;
*/
4public static ArrayList getSingle(ArrayList list) {
44ArrayList newList = new ArrayList(); //创建一个新集合
44Iterator it = list.iterator(); //获取迭代器
44while(it.hasNext()) { //判断老集合中是否有元素
444String temp = (String)it.next(); //将每一个元素临时记录住
444if(!newList.contains(temp)) { //如果新集合中不包含该元素
4444newList.add(temp); //将该元素添加到新集合中
444}
44}
44return newList; //将新集合返回
4}
4
4//可以处理比较对象的类
4private static ArrayList getSingleObj(ArrayList objList) {
44ArrayList newList = new ArrayList();
44Iterator it = objList.iterator();
44while(it.hasNext())
44{
444Object obj = it.next();
444if(!newList.contains(obj))
444{
4444newList.add(obj);
444}
44}
44return newList;
4}
}


集合泛型

泛型概述:比如Collection集合上有一个尖括号<引用数据类型>,一旦设置引用数类型限定您集合存储的数据类型,只能使用引用对象及该对象的子类对象(父类可以指向子类对象);

泛型好处:

  • 提高安全性(将运行期的错误转换到编译期)
  • 省去强转的麻烦

泛型基本使用:

  • <>中放的必须是引用数据类型,从而限定集合中使用的数据类型;

泛型使用注意事项:

#前后的泛型必须一致
ArrayList<Students> lt = new ArrayList<Students>()

#或者后面的泛型可以省略不写(1.7的新特性菱形泛型)
ArrayList<Students> lt = new ArrayList<>()

基础示例:

package com.weiyi.generic;
import java.util.ArrayList;
import java.util.Iterator;

//引用我们students类
import com.weiyi.Collection.Students;
public class Demo1_Generic {
4public static void main(String[] args) {
44//示例0.泛型的使用(字符串类型)
44ArrayList<String> list = new ArrayList<>(); //泛型可以省略不写(1.7的新特性菱形泛型)
44list.add("a");
44list.add("b");
44list.add("c");
44Iterator<String> llt = list.iterator();
44while(llt.hasNext()) {
444System.out.println(llt.next());
44}
44
44//示例1.ArrayList存储字符串并遍历泛型版
44ArrayList<Students> lt = new ArrayList<Students>();//关键点1 数据引用类型一定要相同,后面也可以是前引用类型的子类或者父类
44lt.add(new Students("渣渣辉",25));
44lt.add(new Students("掌门人",22));
44lt.add(new Students("柳师傅",21));
44
44Iterator<Students> ltr = lt.iterator(); //关键点2(注意泛型集合是什么类型,迭代器便是什么类型)
44while(ltr.hasNext())
44{
444Students obj = ltr.next(); //这里不用强转
444System.out.println(obj.getName() +" ---- "+ obj.getAge()); //注意这里如果调用一次.next()指向的就是下一个对象
44}
44/***
* 执行结果:
* 渣渣辉 ---- 25
* 掌门人 ---- 22
* 柳师傅 ---- 21
**/
44
44//示例2.泛型的由来:通过Object转型问题引入
44/* 早期的Object类型可以接收任意的对象类型,但是在实际的使用中,会有类型转换的问题。
* 也就存在这隐患,所以Java提供了泛型来解决这个安全问题。
**/
44Tool t = new Tool(); //创建工具类对象
44t.setObj(new Person("张三",24)); //父类指向子类对象
44
44Worker w = (Worker) t.getObj(); //向下转型
44System.out.println(w); //会出现ClassCastException
44//其实泛型就像是种瓜得瓜种豆得豆一样
44/***执行结果
* Exception in thread "main" java.lang.ClassCastException: com.weiyi.generic.Person cannot be cast to com.weiyi.generic.Worker
at com.weiyi.generic.Demo1_Generic.main(Demo1_Generic.java:47)
*/
4}
}

//示例2演示
class Tool{
4private Object obj;
4//alt + shift + s + r
4public Object getObj() {return obj;}
4public void setObj(Object obj) {
44this.obj = obj; //父类引用子类对象
4}
}

//继承类
class Person extends Students {
4public Person() {super();}
4public Person(String name, int age) {super(name, age);}
}

class Worker extends Students {
4public Worker() {super();}
4public Worker(String name, int age) {super(name, age);}
}


泛型类/方法/接口的概述及使用

泛型类概述: 把泛型定义在类上
定义格式: public class 类名<泛型类型1,…>

泛型方法概述: 把泛型定义在方法上,如果是静态方法需要在static后加入自己的泛型;
定义格式: public <泛型类型> 返回类型 方法名(泛型类型 变量名)

泛型接口概述: 把泛型定义在接口上
定义格式: public interface 接口名<泛型类型>

基础案例:

package com.weiyi.generic;
public class Demo2_Generic {
4public static void main(String[] args) {
44//示例1.泛型类的使用
44Tools<String> tls = new Tools<>();
44tls.show("Hello World!");
44tls.showMethod("Yes");
44tls.showStatic("Generic");
44
44//示例2.接口泛型
44Demo d1 = new Demo();
44d1.show("Interfaces");
44
44Demo1<String> d2 = new Demo1();
44d2.show("Interfaces");
4}
}

//示例1.泛型类(一个字符大写 常用E)
class Tools<Q> {
4private Q obj; //泛型传入是什么类型就是什么类型
4public Q getObj() {return obj;}
4public void setObj(Q obj) {this.obj = obj;}
4public void show(Q str) {
44System.out.println("类泛型:"+str);
4}
4//示例2.方法泛型最好与类的泛型是一致,如果不一致需要在方法上声明该泛型
4public<T> void showMethod(T t) {
44System.out.println("方法泛型:"+t);
4}
4//示例3.注意:类中静态方法随着类的加载而加载,在加载的时候可能还没出现对象;所以说在静态方法泛型上也必须声明自己的泛型
4public static<W> void showStatic(W w) {
44System.out.println("静态方法泛型:"+w);
4}
}
//示例2.泛型接口(一个字符大写 常用E)
interface Inter<T> {
4public void show(T t);
}
//方式1:推荐方式
class Demo implements Inter<String> {
4@Override
4public void show(String t) {
44System.out.println("泛型接口-示例1:"+t);
4}
}
//方式2:没有必要在使用接口的时候指定泛型
class Demo1<T> implements Inter<T>
{
4@Override
4public void show(T t) {
44System.out.println("泛型接口-示例2:"+t);
4}
}

执行结果:

类泛型:Hello World!
方法泛型:Yes
静态方法泛型:Generic
泛型接口-示例1:Interfaces
泛型接口-示例2:Interfaces

注意事项: 泛型类型必须是引用类型;


泛型高级之通配符

描述:泛型通配符<?>, 任意类型如果引用类型没有明确,那么就是Object以及任意的Java类了;

? extends E  向下限定,E及其子类
? super E 向上限定,E及其父类

基础实例:

package com.weiyi.generic;
import com.weiyi.Collection.Students;
import java.util.ArrayList;
import java.util.List;
public class Demo3_Generic {
4public static void main(String[] args) {
44//实例1.当右边的泛型不确定时,左边可以指定为?
44List<?> list = new ArrayList<Integer>();

44//实例2.通配符案例验证
44ArrayList<Study> list1 = new ArrayList<>();
44list1.add(new Study("1.王老五", 15)); //子类
44list1.add(new Study("2.王老吉", 15));
44list1.add(new Study("3.王老四", 15));
44
44ArrayList<Students> list2 = new ArrayList<>();
44list2.add(new Students("4.测试",25)); //父类
44list2.add(new Students("5.学生类",25));

44list2.addAll(list1); //父类添加拼接子类的集合 (注意不能父类强制转换成为子类list1.addAll(list2))
44System.out.println("输出结果:"+list2);
4}
}

//实例1
class Study extends Students {
4public Study() {
44super();
4}
4public Study(String name, int age) {
44super(name, age);
4}
}

执行结果:

输出结果:[Students [name=4.测试, age=25], Students [name=5.学生类, age=25], Students [name=1.王老五, age=15], Students [name=2.王老吉, age=15], Students [name=3.王老四, age=15]]


集合框架进阶

1.增强for的概述和使用
概述:简化数组和Collection集合的遍历,增强for循环底层由迭代器实现;

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

基础实例:

//#实例
package com.weiyi.generic;
import java.util.ArrayList;
import com.weiyi.Collection.Students;
public class Demo4_For {

4public static void main(String[] args) {
44//实例1.增强for遍历数组
44int[] arr = {11,22,33,44,55};
44//foreach 迭代(值得学习)
44for (int i : arr) {
444System.out.print(i+" ");
44}
44System.out.println();
44

44//实例2.增强for遍历集合存储元素
44ArrayList<String> list = new ArrayList<String>();
44list.add("a");
44list.add("b");
44list.add("c");
44list.add("d");
44for (String param : list) {
444System.out.print(param+" ");
44}
44System.out.println();

44
44//实例3.ArrayList存储字符串和自定义对象并遍历增强for版
44ArrayList<Students> list1 = new ArrayList<Students>();
44list1.add(new Students("渣渣哥", 27));
44list1.add(new Students("刘师傅", 26));
44list1.add(new Students("帐老师", 27));
44
44for (Students param : list1) {
444System.out.println(param); //这里是由于重写了toString的效果
44}
4}
}

//#执行结果:
11 22 33 44 55
a b c d
Students [name=渣渣哥, age=27]
Students [name=刘师傅, age=26]
Students [name=帐老师, age=27]


2.三种迭代的能否删除

  • 普通for循环,可以删除,但是索引要– (自减)
  • 迭代器,可以删除,但是必须使用迭代器自身的remove方法,否则会出现并发修改异常
  • 增强for循环不能删除
    基础实例:
    package com.weiyi.generic;
    import java.util.ArrayList;
    import java.util.Iterator;
    import com.weiyi.Collection.Students;
    public class Demo5_RemoveCollection {
    4public static void main(String[] args) {
    44//实例1.三种迭代方法是否能进行删除
    44ArrayList<String> list = new ArrayList<String>();
    44list.add("a");
    44list.add("a");
    44list.add("b");
    44list.add("c");
    44list.add("WeiyiGeek");


    44//(1)如果要删除的元素是挨着的,普通循环只能对其index索引减减<-重点
    44for (int i = 0; i < list.size(); i++) {
    444if("a".equals(list.get(i)))
    4444list.remove(i--); //注意这里是先赋值,再减减
    44}
    44
    44//(2)迭代器删除
    44Iterator<String> it = list.iterator();
    44while(it.hasNext())
    44{
    444if("b".equals(it.next()))
    4444//注意这里不能使用集合的删除方法会导致并发修改异常(迭代过程中进行了修改),因为迭代过程中如果集合被修改,便会导致迭代修改异常
    4444it.remove();
    44}
    44
    44//宁一种方式 与上面的区别就是 不能重复使用迭代器it1
    44for(Iterator<String> it1 = list.iterator(); it.hasNext();)
    44{
    444if("c".equals(it1.next()))
    4444it1.remove();
    44}
    44
    44
    44//(3)增强for循环不能删除只可以遍历
    44for(String param: list){
    444if("c".equals(param))
    4444//list.remove(param);
    4444System.out.println(param);
    44
    444System.out.println("外层 : " + param);
    44}
    44System.out.println(list);
    4}
    }

执行结果:

c
外层 : c
外层 : WeiyiGeek
[c, WeiyiGeek]


3.集合嵌套之ArrayList嵌套ArrayList
基础示例:

import java.util.ArrayList;

import com.weiyi.Collection.Students;

public class Demo3_ArrayLists {

4public static void main(String[] args) {
44//示例:集合嵌套ArrayList中的ArrayList
44ArrayList<ArrayList<Students>> list = new ArrayList<ArrayList<Students>>(); //当做一个年级
44ArrayList<Students> first = new ArrayList<Students>(); //第一个班级
44first.add(new Students("张伟",25));
44first.add(new Students("大张伟",25));
44first.add(new Students("纳音",25));

44ArrayList<Students> seconde = new ArrayList<Students>(); //第二个班级
44seconde.add(new Students("Love", 99));
44seconde.add(new Students("Test", 199));

44//将班级加到年级集合中
44list.add(first);
44list.add(seconde);
44
44//遍历学科集合(值得学习)
44for (ArrayList<Students> x: list) {
444for (Students y : x) {
4444System.out.println(y);
444}
44}
4}
}
#执行结果
Students [name=张伟, age=25]
Students [name=大张伟, age=25]
Students [name=纳音, age=25]
Students [name=Love, age=99]
Students [name=Test, age=199]


集合异常

问题1:集合框架(并发修改异常产生的原因及解决方案)
ListIterator常用方法:

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

案例演示需求:我有一个集合,请问,我想判断里面有没有”world”这个元素,如果有,我就添加一个”javaee”元素,请写代码实现。

package com.weiyigeek.Collection;

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

public class Demo5_ListIterator {

4public static void main(String[] args) {
44//方式1:
44List list = new ArrayList();
44list.add("Weiyi");
44list.add("world");
44list.add("Geek");
44
44//采用:常规Iterator迭代器
44Iterator it = list.iterator();
44boolean flag = false;
44while(it.hasNext())
44{
444String str = (String)it.next();
444if(str.equals("world")) {
444//list.add("JavaEE") //这里会抛出ConcurrentModificationException并发修改异常
444//迭代器遍历集合修改集合,异常由于迭代器已经知道集合的个数,然而在迭代的时候又添加了集合元素所以导致异常
444//所以采用此种方法
4444flag = true;
4444break;
444}
44}
44if(flag) {
444list.add("JavaEE");
44}
44System.out.println("方法1:" + list);
44
44
44//方式2:
44//* a:迭代器迭代元素,迭代器修改元素(ListIterator的特有功能add)
44//* b:集合遍历元素,集合修改元素
44ListIterator lit = list.listIterator(); //如果想在遍历的过程中添加元素,可以用ListIterator中的add方法
44while(lit.hasNext()) {
444String str = (String)lit.next();
444if(str.equals("world")) {
4444//它会立即在找到world后面进行添加javaee
4444lit.add("javaee"); //关键点 lit的 ListIterator在迭代的过程中添加元素对象;
444}
44}
44System.out.println("方式2:"+list);
4}
}

//###########执行结果##############
方法1:[Weiyi, world, Geek, JavaEE]
方式2:[Weiyi, world, javaee, Geek, JavaEE]