本文主要介绍Collection集合、迭代器、泛型的定义以及详细的使用方法。
目录
Collection集合
1.集合定义
2.集合和数组的区别
3.Collection集合常用功能
Iterator迭代器
1.Iterator接口
2.增强for循环
泛型
1.概念
2.为什么要用泛型
3.定义与使用
总结
集合是Java中提供一种容器,可以用来存储不同类型的数据对象。
a. 数组的长度是固定的,定义后就不能改变。集合的长度是可变的。
b. 数组中存储的是同意类型的元素,只能存储基本数据类型值。集合存储的都是对象,而且对象的类型可以不一致。
在开发中一般当对下岗多的时候,使用集合进行存储。
定义:Collection是所有单列集合的父接口,因此在Collection中定义了单列集合(List和Set)通用的一些方法,这些方法可用于操作所有的单列集合。
实例:()
package demo1_Collection;
import java.util.ArrayList;
import java.util.Collection;
/*
java.util.Collection接口:
所有单列集合的最顶层的接口,里面定义了所有单列集合共性的方法
任意的单列集合都可以使用Collection接口中的方法
共性方法:
- public boolean add(E e): 把给定的对象添加到当前集合中 。
- public void clear() :清空集合中所有的元素。
- public boolean remove(E e): 把给定的对象在当前集合中删除。
- public boolean contains(E e): 判断当前集合中是否包含给定的对象。
- public boolean isEmpty(): 判断当前集合是否为空。
- public int size(): 返回集合中元素的个数。
- public Object[] toArray(): 把集合中的元素,存储到数组中。
*/
public class Test01_Collection {
public static void main(String[] args) {
// Collection collection= demo1_Add();
// demo2_Remove();
// demo3_Clear();
// demo4_Contains();
// demo5_IsEmpty();
// demo6_Size();
demo7_ToArray();
}
public static void demo7_ToArray(){
Collection collection= demo1_Add();
// Object[] toArray()转换成一个Object数组
Object[] arr=collection.toArray();
//遍历数组
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
public static void demo6_Size(){
Collection collection= demo1_Add();
int size=collection.size();
System.out.println(size); // 3
}
public static void demo5_IsEmpty(){
Collection collection= demo1_Add();
boolean b1=collection.isEmpty();
collection.clear();
boolean b2=collection.isEmpty();
System.out.println(b1+"==="+b2); //false===true
}
public static void demo4_Contains(){
Collection collection= demo1_Add();
boolean b1=collection.contains("小太阳");
boolean b2=collection.contains("小兔崽子");
System.out.println(b1+"==="+b2); //true===false
}
public static void demo3_Clear(){
Collection collection=demo1_Add();
System.out.println(collection); //[小太阳, 小月亮, 小星星]
collection.clear();
System.out.println(collection); //[]
}
public static Collection demo1_Add() {
/*
- public boolean add(E e): 把给定的对象添加到当前集合中 。
返回值为Boolean值,一般为true,所有不用接收
*/
//创建集合对象,可以使用多态
Collection collection = new ArrayList<>();
boolean b = collection.add("小太阳");
collection.add("小月亮");
collection.add("小星星");
return collection;
}
public static void demo2_Remove() {
/*
- public boolean remove(E e): 把给定的对象在当前集合中删除。
存在元素,删除元素,返回true
不存在删除元素,返回false
*/
//创建集合对象,可以使用多态
Collection collection =demo1_Add();
boolean b1 = collection.remove("小星星");
boolean b2 = collection.remove("小兔崽子");
System.out.println(b1 + " " + b2); //true false
System.out.println(collection);
}
}
Iterator
主要用于迭代访问(即遍历)Collection
中的元素,因此Iterator
对象也被称为迭代器。
迭代:即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。
Iterator接口常用方法:
- public E next():返回迭代的下一个元素。
- public boolean hasNext():如果仍有元素可以迭代,则返回 true。
迭代器使用步骤:
a.获取迭代器的实现类对象,用Iterator接口接收
b.使用Iterator接口中hasNext方法判断还有没有下一个元素
c.使用Iterator接口的方法next()取出集合的下一个元素
实例:
package demo2_Iterator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/*
java.util.Iterator接口:迭代器(对单列集合进行遍历)
常用方法:
- public boolean hasNext() 如果仍有元素可以迭代,则返回true。
判断集合中还有没有下一个元素,有则返回true,否则返回false
- public E next() 返回迭代的下一个元素,就是取出集合中的下一个元素
Iterator迭代器是一个接口,需要使用Iterator接口的实现类对象。
- public Iterator iterator(): 获取集合对应的迭代器,用来遍历集合中的元素的。
迭代器的使用步骤:
1.获取迭代器的实现类对象,使用Iterator接口接收
2.使用Iterator接口中的方法hasNext判断还有没有下一个元素
3.使用Iterator接口的方法next取出集合中的下一个元素
*/
public class Test01_Iterator {
public static void main(String[] args) {
//创建对象
Collection collection=new ArrayList<>();
//添加元素
collection.add("小太阳");
collection.add("小月亮");
collection.add("小星星");
/*
1.使用集合中的方法iterator()获取迭代器的实现类对象,使用iterator接口接收(多态)
注意:
Iterator 接口也是有泛型的,迭代器的泛型跟着集合走,集合是什么类型,迭代器就是什么泛型
*/
//多态 接口 实现类对象
//获取迭代器的实现类对象,并把指针(索引)指向集合的-1索引
Iterator it=collection.iterator();
//泛型指的是 迭代出元素的数据类型
while(it.hasNext()){ //2.判断释放有迭代元素
String str=it.next(); //3.获取迭代出的元素
System.out.println(str);
}
}
}
增强for循环(也称for each循环)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。它的内部原理其实是Iterator迭代器,所以遍历的过程中,不能对集合中的元素进行增删操作(否则会报错)。
格式:
for(集合/数组的数据类型 变量名 : 集合名/数组名){
System.out.println(变量名);
}
实例:(它用于遍历Collection和数组。通常只进行遍历元素,不要在遍历的过程中对集合元素进行增删操作 !!!)
重要的事情说两遍!!!
package demo2_Iterator;
import java.util.ArrayList;
import java.util.Collection;
//增强for循环实例
public class Test02_For {
public static void main(String[] args) {
//创建集合对象
Collection collection=new ArrayList<>();
collection.add("会发光啊");
collection.add("小太阳");
collection.add("小月亮");
//使用增强for循环打印
for(String str : collection){
System.out.print(str+" "); //会发光啊 小太阳 小月亮
}
}
}
泛型:是一种未知的数据类型,当我们不知道使用什么数据类型的时候,可以使用泛型
泛型也可以看作是一个变量,用来接收数据类型
E e: Element 元素
T t: Type 类型
定义集合的时候经常用到泛型,例如ArrayList
在前面学习集合的时候,我们都知道集合中是可以存放任意对象的,只要把对象存储集合后,那么这时他们都会被提升成Object对象。当我们取出每一个对象,并且进行相应的操作,这时候必须采用类型转换。
举例如下:
package demo3_Generic;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
//为什么使用泛型
public class Test03_Generic {
public static void main(String[] args) {
//创建集合对象
Collection collection=new ArrayList();
//集合没有做限定,默认存储Object对象
collection.add("小太阳");
collection.add(520);
collection.add("会发光啊");
Iterator iterator=collection.iterator();
while (iterator.hasNext()){
//需要打印每个元素的长度,就要把迭代出的每个对象转成Strinl类型
String str=(String )iterator.next();
System.out.print(str+" ");
}
}
}
结果报错:(java.lang.ClassCastException)--类型转换异常
小太阳 Exception in thread "main" java.lang.ClassCastException: java.base/java.lang.Integer cannot be cast to java.base/java.lang.String
at demo3_Generic.Test03_Generic.main(Test03_Generic.java:20)
Process finished with exit code 1
为什么会发生类型转换异常呢?
由于集合中什么类型的元素都可以存储。导致取出时强转引发运行时 ClassCastException。
解决方案:
Collection虽然可以存储各种对象,但实际上通常Collection只存储同一类型对象。例如都是存储字符串对象。因此在JDK5之后,新增了泛型(Generic)语法,让你在设计API时可以指定类或方法支持泛型,这样我们使用API的时候也变得更为简洁,并得到了编译时期的语法检查。
A. 含有泛型的类:创建对象的时候确定泛型的数据类型
实例:
创建含有方法的类
package demo3_Generic;
/*
定义一个含有泛型的类,模拟ArrayList集合
泛型是一种未知的数据类型,当我们不确定用什么数据类型的时候,可以使用泛型
泛型可以接收任意的数据类型
创建对象的时候确定泛型的数据类型
*/
public class Test01_StudentGeneric {
private E name;
public E getName(){
return name;
}
public void setName(E name){
this.name=name;
}
}
创建类对象并确定泛型的数据类型,调用类方法:
package demo3_Generic;
public class Student_Test {
public static void main(String[] args) {
//创建对象的时候确定泛型的数据类型,不写泛型默认为Object类型
Test01_StudentGeneric sc=new Test01_StudentGeneric();
sc.setName("没有写泛型默认Object类型");
Object obj=sc.getName();
System.out.println(obj); // 没有写泛型默认Object类型
//创建对象,泛型使用String类型
Test01_StudentGeneric stu=new Test01_StudentGeneric<>();
stu.setName("小太阳啊");
System.out.println(stu.getName()); //小太阳啊
}
}
B. 含有泛型的方法:在调用方法的时候确定泛型的数据类型,传递什么类型参数,泛型就是什么类型
实例:
package demo3_Generic;
/*
定义含有泛型的方法: 泛型定义在方法的修饰符和返回值之间
格式:
修饰符 <泛型> 返回值类型 方法名(使用泛型){
方法体
}
含有泛型的方法,在调用方法的时候确定泛型的数据类型
传递什么类型的参数,泛型就是什么类型
*/
public class Test02_PersonGeneric {
//定义一个含有泛型的方法
public void method1(T t){
System.out.println(t);
}
//定义一个含有泛型的静态方法
public static void method2(T t){
System.out.println(t);
}
}
调用方法:可以传递任意类型的参数。
package demo3_Generic;
//测试含有泛型的方法
public class Person_Test {
public static void main(String[] args) {
//创建对象
Test02_PersonGeneric per=new Test02_PersonGeneric();
/*
调用含有泛型的方法
传递什么类型的参数,泛型就是什么类型
*/
per.method1("小太阳"); //小太阳
per.method1(123); //123
//调用含有泛型的静态方法
Test02_PersonGeneric.method2("会发光啊"); //会发光啊
}
}
C.定义含有泛型的接口
第一种使用方式:定义接口的实现类,实现接口,在实现类中指定接口的泛型。
第二种使用方式:创建对象的时候确定泛型的类型。接口使用什么泛型,实现类就使用什么泛型,类跟着接口走,就相当于定义 了一个含有泛型的类。
实例: 第一种:
定义接口和实现类:(为了省略篇幅,把接口和实现类放一块了,阅读博客时建议自己手动打一边,切勿直接复制粘贴。。。)
//接口
package demo3_Generic;
/*
定义含有泛型的接口:
修饰符 interface接口名<代表泛型的变量> { }
*/
public interface Interface_Generic{
abstract void show(T t);
}
//==================================
//实现类
package demo3_Generic;
/*
含有泛型的接口第一种使用方式:定义接口的实现类,实现接口,指定接口的泛型
举个例子:
定义一个接口
public interface Iterator{
E next();
}
Scanner类实现了Iterator接口,并指定接口的泛型为String,所以重写的next方法
泛型默认就是String类型
public final class Scanner implements Iterator{
public String next(){}
}
*/
public class Interface_GenericImpl implements Interface_Generic {
@Override
public void show(String s){
System.out.println(s);
}
}
第二种:
//接口
package demo3_Generic;
//定义含有泛型的接口
public interface Interface_Generic2 {
void get(int index);
}
//================================
//实现类
package demo3_Generic;
/*
含有泛型的接口第二种使用方式:接口使用什么泛型,实现类就使用什么泛型,类跟着接口走,就相当于定义
了一个含有泛型的类,创建对象的时候确定泛型的类型。
实例:public interface List{
E get(int index);
}
public class ArrayList implements List{
@Override
public E get(int index){}
}
*/
public class Interface_GenericImpl2 implements Interface_Generic2{
@Override
public void get(int index){
System.out.println(index);
}
}
测试类:
package demo3_Generic;
//测试含有泛型的接口实现类
public class Interface_GenericImpl_Test {
public static void main(String[] args) {
//测试第一种含有泛型的接口使用方式
Interface_GenericImpl inter=new Interface_GenericImpl();
inter.show("会发光的小太阳"); //会发光的小太阳
//测试第二种含有泛型的接口使用方式
Interface_GenericImpl2 inter2=new Interface_GenericImpl2<>();
inter2.get(520); //520
}
}
花了两个多小时整理下今天学的东西,个人觉得关于泛型的定义和使用还算蛮详细的,这一块议自己手动打一遍。关于集合类整理的不是很全面,过两天学习Map和Set,学习过后再把集合类这一块整理一下。
最近周围毕业的小伙伴陆陆续续的都开始工作,而自己还在培训,有时候总能感觉到和别人的巨大落差,还有就是感觉有时候在一些方向选择总是耽误时间,比如这个培训完全可以在上半年在学校的空白期去培训,这样可以在8月份结束,张阿森他们做选择就干脆果断,3月份就开始培训,下个月就要结束了去搞钱了。
很想套用插翅难逃里张世豪的一句话:”我现在其他的什么都不想,我就像搞钱,我要变富“。我也想早点找到工作搞钱啊。。。也不知道培训完是什么情况,能不能找到好的工作。
啥也别想了,现在刚把学费交了,还是先好好学习吧!!!(强行给自己打鸡血---)