1、集合基础
1.1 Collection 总结
1.1.1 概述:
- 集合:是Java中提供的一种容器技术,可以用来存储多个数据
- 集合和数组都是容器,它们区别为:
- 数组长度是固定的,集合的长度是可变的
- 数组中存储的是同一类型的元素,可以存储基本类型值,集合存储的都是对象,而且对象的类型可以不一致。
1.1.2 框架
集合按照存储结构分为两大类,分别是:单列集合 java.util.Collection 和双列集合 java.util.Map
- Collection:单列表集合类的根接口,用于储存一系列符合某种规则的元素,它由两个重要的子接口,分别是:java.util.List 和 java.util.Set。其中,List的特点是:元素有序(添加时的什么顺序,输出时也什么顺序),而且可以重复(内容一样);Set特点是:元素无序(输出时无序),而且元素不可以重复。
- List接口的主要实现类
- java.util.ArryList
- java.util.LinkedList
- java.util.Vector
- Set接口的主要实现类
- java.util.HashSet
- java.util.LinkHashSet
- java.util.TreeSet
- 集合本身是一个工具类,它存放在Java.util 包中
1.1.3 Collection 常用功能
Collection 是所有单列集合的父接口,因此在Collection 中定义了单列集合的一些方法。
- public boolean add(Object e): 把给定的对象添加到当前集合中
- public boolean addAll(Collection<? extends E> c ):将指定集合的所有元素都添加到此集合中
- public void clear():从此集合中删除所有的元素
- public boolean contains(Object o):如果此集合中包含指定的元素,则返回true
- public boolean isEmpty():判断当前集合是否为空
- public boolean remove(Object o):从该集合中删除指定元素的单个实例
- public int size():返回集合中元素的个数
- public Object[] toArry() :把集合中元素,存储到数组中
1.2 Iterator 迭代器
1.2.1 Iterator 接口
- 需要遍历集合的所有元素,则使用接口 java.util.Iterator。Iterator 也是集合的一员,但它与Collection、map接口不同,Collection 接口与map接口主要用于存储元素,而Iterator 主要用于迭代,遍历,所以又被称为迭代器
- 遍历
- public Iterator iterator():获取集合对应的迭代器,用来遍历数组
- 迭代的概念:
- 迭代:即Collection 集合元素的通用获取方法,再去元素之前要先判断集合中有没有元素,如果有就把这个元素取出来,再继续判断,如果还有就继续取出来,一直到没有,称为迭代
- Iterator 常用方法
- public E next():返回迭代的下一个元素
- public boolean hasNext():如果仍又元素可以迭代返回true
package com.bdit.test;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
public class Test13 {
public static void main(String[] args) {
Collection collection = new HashSet();
collection.add("zhangsan");//添加一个Object类型的元素
collection.add(123);
collection.add(true);
System.out.println(collection);
Collection collection1 = new HashSet();
collection1.addAll(collection);//把整个集合添加到此集合中
System.out.println(collection1+"============");
System.out.println("--------------------------------------------");
collection1.clear();//从此集合中删除所有元素。
System.out.println(collection1);
System.out.println(collection1.contains("lisi"));//查询集合中有无括号里的元素,有则返回true
System.out.println(collection1.containsAll(collection));//如果此集合包含指定集合中的所有元素,则返回 true 。
System.out.println("====================================================");
collection1.add("wangwu");
System.out.println(collection1.equals("wangwu"));//将指定的对象与此集合进行比较以获得相等性。
System.out.println(collection1.remove("wangwu"));//删除指定元素,输出true/false
System.out.println(collection1);
collection1.add("甲一");
System.out.println(collection1.size());
System.out.println("-------------------------------------------------------");
Object[] str = collection1.toArray();//返回一个包含此集合中所有元素的数组。
for (int i = 0; i < str.length; i++) {
System.out.print(str[i]+" ");
}
System.out.println();
System.out.println(collection1.toArray());
}
}
1.2.2 迭代器的实现原理
- 当遍历集合时,通过Iterator() 方法获取迭代器对象,然后使用hasNext() 方法判断集合中是否存在下一个元素,如果有就用next() 方法取出,否则说明已经到达了集合的末尾,停止遍历
- Iterator 迭代器工作时,内部采用指针的方式来跟踪集合中的个元素。
- 在调用 next() 方法之前,迭代器的索引位于第一个元素之前,不指向任何元素,当第一次调用迭代器方法时,迭代器的索引就会往后移一位,指向第一个元素并将该元素返回,当再次调用next() 方法时,迭代器索引就会指向第二个索引的位置,并且将该元素返回,依次类推,知道hasNext() 方法返回false 时,就代表都遍历完成,此时到达了集合的尾部,终止对该集合的遍历
1.3 增强for循环
1.3.1 概述
- 增强for() 循环也称(for each 循环)是JDK1.5 之后新增的一个高级for循环,专门用来遍历的,它的内部其实是一个 Iterator 迭代器,所以在遍历过程中,不能对集合进行其它操作
- 使用增强for() 循环不能直接获取每个元素的下标值
- 增强for() 循环,知识和对数组或者集合进行遍历
- for(数据类型 变量名:循环数组或者集合){ 方法体 }
package com.bdit.test;
import java.util.ArrayList;
public class Test01 {
public static void main(String[] args) {
int[] in01 = {1,2,3,4,5};
for (int a:in01){
System.out.print(a+" ");
}
System.out.println();
int[] in02 = {6,7,8,9};
int in001 = 0;//下标值
for (int a:in02){
System.out.print(a+" ");
// System.out.print(in02[in001]+" ");//通过下标
in001++;
}
}
}
1.4 泛型
1.4.1 概述
- 泛型:就是一种不确定的数据类型,用来消除数据类型转换
- 泛型可以省略,如果省略,默认泛型就是Object类型
- 好处:
- 省略了强转的代码
- 可以把运行时的问题提前到编译时期
- 泛型:可以在类或方法中预支地使用未知的类型
1.4.2 泛型的定义和使用
- 集合类<泛型类型> 对象名 = new 集合类<>();
package com.bdit;
import java.util.ArrayList;
import java.util.Collection;
public class Test5 {
public static void main(String[] args) {
Collection<Student> c1=new ArrayList<>();
c1.add(new Student(1001,"张三",22));
c1.add(new Student(1002,"李四",23));
c1.add(new Student(1003,"王五",24));
c1.add(new Student(1004,"赵六",25));
for (Student stu:c1){
System.out.println(stu);
}
}
}
- 定义和使用含有泛型的类
- 定义格式:
- 修饰符 class 类名<代表泛型的变量>{ }
自定义泛型类
package com.bdit;
public class Test6 {
public static void main(String[] args) {
MyClass<String> myClass=new MyClass<>();
myClass.setName("张三");
System.out.println(myClass.getName());
}
}
class MyClass<MVP>{
private MVP name;
public void setName(MVP name){
this.name=name;
}
public MVP getName(){
return name;
}
}
- 在创建泛型类对象是,必须给泛型类确定为具体的类型
1.4.3 含有泛型的方法
- 修饰类<代表泛型的变量> 返回值类型 方法名(参数列表){ }
package com.bdit.test;
public class Test16 {
private String name;
private int age;
int num ;
public Test16(){}
public Test16(String name,int age,int num){
this.name=name;
this.age=age;
this.num=num;
}
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;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public String toString() {
return "Test16{" +
"name='" + name + '\'' +
", age=" + age +
", num=" + num +
'}';
}
}
泛型:
package com.bdit.test;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
//泛型
//格式:
// 类名<数据类型> 方法名 = new HashSet<>()
public class Test16_01 {
public static void main(String[] args) {
Collection<String> collection = new HashSet<>();//定义类型只能是String
collection.add("张三");
collection.add("张四");
collection.add("张五");
// collection.add(123); 报错
System.out.println(collection);
Collection<Test16> collection1 = new HashSet<>();
collection1.add(new Test16("甲一",25,1001));
for (Test16 test16: collection1){
System.out.println("for的 "+test16);
}
Iterator it = collection1.iterator();
while (it.hasNext()){
System.out.println("iterator的 "+it.next());
}
System.out.println("-----------------------------------------------------------------------");
Collection<Test16> collection2 = new HashSet<>();
collection2.add(new Test16("甲二",15,1002));
for (Test16 test16:collection2){
System.out.println(test16);
}
}
}
【无论使用泛型类、泛型方法、泛型接口,传递的泛型类型只能是引用类型】
1.4.4 含有泛型的接口
- 格式:
- 修饰符 interface 接口名<代表泛型的变量>{ }
package com.bdit;
/*
泛型接口
*/
public class Test8 {
public static void main(String[] args) {
MyImpl1<String> myImpl1=new MyImpl1<>();
myImpl1.add("张三");
}
}
interface MyInter<E>{
public void add(E e);
public E get();
}
//定义实现类
class MyImpl1<E> implements MyInter<E>{
@Override
public void add(E e) {
}
@Override
public E get() {
return null;
}
}
【不能直接new泛型变量的对象,因为无法保证泛型变量就一定是类】
1.4.5 泛型通配符
当使用泛型类或接口时,传递的数据中,泛型类型不确定,可以通过通配符<>表示,但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合元素自身方法无法使用。
通配符基本使用
- 泛型的通配符:不知道使用什么类型来接收数据的时候,此时可以使用?,?表示未知通配符,此时只能接收数据,不能往该集合中存储数据。
package com.bdit;
import java.util.ArrayList;
import java.util.Collection;
public class Test9 {
public static void main(String[] args) {
Collection<Integer> list1=new ArrayList<>();
getElement(list1);
}
public static void getElement(Collection<?> coll){
for(Object o:coll){
System.out.println(o);
}
}
public static void getElement2(Collection coll){
for(Object o:coll){
System.out.println(o);
}
}
}
1.4.6 通配符高级使用 – 受限泛型
前面设置的泛型,实际上可以是任意类型,但是Java中的泛型也可以设置一个泛型的上限和下限
- 泛型的上限:
- 格式: 类型名称<? extends 类>对象名称
- 意义:只能接收该类以及子类类型
- 泛型的下限
- 格式:类型名称<? super 类>对象名称
- 意义:只能接收该类型以及父类类型
package com.bdit;
import java.util.ArrayList;
import java.util.Collection;
public class Test10 {
public static void main(String[] args) {
Collection<Integer> c1=new ArrayList<>();
display1(c1);
display2(c1);
Collection<Number> c2=new ArrayList<>();
display1(c2);
display2(c2);
Collection<Double> c3=new ArrayList<>();
display2(c3);
}
//泛型上限
public static void display1(Collection<? extends Number> coll){
}
//泛型下限
public static void display2(Collection<? super Integer> coll){
}