JAVA入门学习六

时间:2022-07-28
本文章向大家介绍JAVA入门学习六,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

[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 {
  private String name;
  private int age;
  //创建空参和有参
  public Students() {
  }
  public Students(String name, int age) {
    this.name = name;
    this.age = age;
  }
  
  //创建get/setter 方法
  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;
  }
}

案例需要上面的学生类

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

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

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

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

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

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

执行结果:

[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 {

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

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

执行结果:

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

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

执行结果:

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 {

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

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

执行结果:

[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()) //判断集合中是否有元素
{
  //迭代获取集合中的元素
  System.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 {
  public static void main(String[] args) {
    //示例1.集合常用方法展示
    LinkedList list = new LinkedList(); //创建Linked对象
    list.add("1");
    list.addFirst("0");
    list.addLast("2");
    
    System.out.println("获取集合中第一个元素:"+list.getFirst());
    System.out.println("获取集合中最后一个元素:"+list.getLast());
    System.out.println("返回删除的第一个元素:"+list.removeFirst());
    System.out.println("返回删除的最后一个元素:"+list.removeLast());
    System.out.println("利用索引获取元素 (原理值得学习): "+list.get(0));
  
    //示例2.采用LinkedList模拟栈结构
    LinkedStack stack = new LinkedStack();
    stack.in("a"); //进栈
    stack.in("b");
    stack.in("c");
    stack.in("d");
    //循环弹栈
    while(!stack.isEmpty()) {
      System.out.println(stack.out());
    }
    
    //示例3.实现堆即先进先出采用addFrist();以及RemoveFrist()即可
  }
}

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

执行结果:

获取集合中第一个元素: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 {
  public static void main(String[] args) 
	{
  /**
	 * A:案例演示
	   * 需求:ArrayList去除集合中字符串的重复值(字符串的内容相同)
	   * 思路:创建新集合方式
	 */
    ArrayList newList = new ArrayList();
    newList.add("a");
    newList.add("c");
    newList.add("b");
    newList.add("b");
    newList.add("b");

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

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

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

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

class Worker extends Students {
  public Worker() {super();}
  public Worker(String name, int age) {super(name, age);}
}
泛型类/方法/接口的概述及使用

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

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

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

基础案例:

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

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

执行结果:

类泛型: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 {
  public static void main(String[] args) {
    //实例1.当右边的泛型不确定时,左边可以指定为?
    List<?> list = new ArrayList<Integer>();

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

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

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

执行结果:

输出结果:[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集合) {
  使用变量即可,该变量就是元素
}

基础实例:

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

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

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

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

//#执行结果:
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 {
  public static void main(String[] args) {
    //实例1.三种迭代方法是否能进行删除
    ArrayList<String> list = new ArrayList<String>();
    list.add("a"); 
    list.add("a");
    list.add("b");
    list.add("c");
    list.add("WeiyiGeek");


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

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

import java.util.ArrayList;

import com.weiyi.Collection.Students;

public class Demo3_ArrayLists {

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

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

    //将班级加到年级集合中
    list.add(first);
    list.add(seconde);
    
    //遍历学科集合(值得学习)
    for (ArrayList<Students> x: list) {
      for (Students y : x) {
        System.out.println(y);
      }
    }
  }
}
#执行结果
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 {

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

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