1.函数式接口(掌握)
概述
有且只有一个抽象方法的接口就是函数式接口。
可以默认方法 静态方法 私有方法。
举例:
Runnable Comparator
代码演示
package com.itheima.sh.function_inter_01;
/*
函数式接口:
有且只有一个抽象方法的接口就是函数式接口。
lambda使用前提:
1.有函数式接口
2.某个方法的参数类型是函数式接口类型
jdk8以后为了验证当前接口是一个函数式接口,增加了一个注解:
@FunctionalInterface
只是用来验证当前接口是否是一个函数式接口,如果不是则报错
*/
@FunctionalInterface
public interface Flyable {
//定义抽象方法
void fly();
public default void test(){
}
}
package com.itheima.sh.function_inter_01;
public class Test01 {
public static void main(String[] args) {
//调用自定义方法show
//这里可以使用lambda完成Flyable中的抽象方法fly
// show(()->{ System.out.println("鸟飞了");});
}
//定义方法,参数是Flyable类型
/*
Flyable f = ()->{
System.out.println("鸟飞了");
}
*/
public static void show(Flyable f){
//使用接口对象调用fly方法
f.fly();
}
}
小结:
1.函数式接口:有且只有一个抽象方法的接口 可以有其他方法
2.从jdk8开始为了验证一个接口是否是一个函数式接口我们增加了一个注解: @FunctionalInterface
3.使用lambda完成函数式接口中抽象方法
常用的函数式接口(掌握)
在jdk8后增加了几个常用的函数式接口,最为常见的是四个。
1.Supplier接口
1.该接口位于java.util.function 使用需要导包
2.该方法主要用来生产对象数据
3.生产方法:抽象方法:
T get() 生产数据 我们需要使用lambda完成生产数据
4.代码演示:
练习1:
package com.itheima.sh.function_inter_02;
import java.util.function.Supplier;
/*
需求:指定泛型是String类型,获取String类的对象。
Supplier<T> 生产接口
T get() 生产数据 我们需要使用lambda完成生产数据
使用lambda的前提:
1.函数式接口
2.某个方法参数类型是函数式接口类型
*/
public class Test01 {
public static void main(String[] args) {
//匿名内部类
/*show(new Supplier<String>() {
@Override
public String get() {
return "abc";
}
});*/
//调用方法使用lambda完成 T get() 生产数据
// show(()->{return "abc";});
show(()->"abc");
}
/*
Supplier<String> s = new Supplier<String>() {
@Override
public String get() {
return "abc";
}
}
*/
public static void show(Supplier<String> s){
//调用get方法
String str = s.get();//abc
System.out.println("生产的对象数据是:"+str);
}
}
练习2:
package com.itheima.sh.function_inter_02;
import java.util.function.Supplier;
/*
需求:指定泛型是String类型,获取String类的对象。
Supplier<T> 生产接口
T get() 生产数据 我们需要使用lambda完成生产数据
使用lambda的前提:
1.函数式接口
2.某个方法参数类型是函数式接口类型
*/
public class Test02 {
public static void main(String[] args) {
//调用方法使用lambda完成 T get() 生产数据
// show(()->{return "abc";});
show(()->"abc");
show(()->123);
show(()->true);
}
//自定义泛型方法
public static <T> void show(Supplier<T> s){
//调用get方法
T t = s.get();
System.out.println("生产的对象数据是:"+t);
}
}
小结:
1.Supplier表示生产对象的函数式接口,我们使用lambda完成抽象方法get
T get() 生产数据 我们需要使用lambda完成生产数据
2.Consumer接口
1.表示消费对象数据的接口,具体如何消费由我们使用lambda完成该函数式接口的抽象方法
void accept(T t) 对给定的参数执行此操作。
2.代码演示
package com.itheima.sh.function_inter_02;
import java.util.function.Consumer;
/*
Consumer<T>接口 消费接口
void accept(T t) 对给定的参数执行此操作。
*/
public class Test03_Consumer {
public static void main(String[] args) {
//调用方法
/* show((String str)->{
//消费
System.out.println(str);
},"jahaha");*/
//str表示void accept(T t) 方法形参名,属于标识符,叫什么都可以
// show(str->System.out.println(str),"jahaha");
show(str->System.out.println(str.length()),"jahaha");
}
//参数类型是Consumer函数式接口类型
/*
Consumer<String> c = (String str)->{
//消费
System.out.println(str);
}
String s = "jahaha"
*/
private static void show(Consumer<String> c,String s) {
//使用接口对象调用方法
c.accept(s);
}
}
小结:
1.Consumer属于消费的函数式接口,需要我们使用lambda完成抽象方法:
void accept(T t) 对给定的参数执行此操作。
3.Predicate接口
1.表示判断的函数式接口,该接口中含有一个判断的抽象方法,我们需要使用lambda完成
boolean test(T t) 如果给定的参数t满足判断条件,那么该方法返回true,不满足返回false
2.代码演示:
package com.itheima.sh.function_inter_02;
import java.util.function.Predicate;
/*
判断函数式接口:Predicate
方法:boolean test(T t) 如果给定的参数t满足判断条件,那么该方法返回true,不满足返回false
*/
public class Test04_Predicate {
public static void main(String[] args) {
//调用方法
/* show(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.length() == 4;
}
}, "锁哥真帅啊");*/
//使用lambda
// show((String str)->{return str.length() == 4;},"锁哥真帅啊");
show(str->str.length() == 4,"锁哥真帅啊");
}
/*
Predicate<String> p = new Predicate<String>() {
@Override
public boolean test(String s) {
return s.length() == 4;
}
}
String s = "锁哥真帅"
*/
private static void show(Predicate<String> p,String s) {
//调用方法
boolean boo = p.test(s);
System.out.println("boo = " + boo);
}
}
图解:
小结:
Predicate表示判断接口我们使用lambda完成判断方法:
boolean test(T t) 如果给定的参数t满足判断条件,那么该方法返回true,不满足返回false
4.Function<T,R>接口
1.该接口表示转换接口,将前置类型T转换为后置类型R
2.我们需要使用lambda完成该接口中的转换方法:
R apply(T t) 将参数T类型转换为R类型
3.代码演示:
需求:将字符串"123"转换为整数123 —》将String类型转换为Integer
分析:
T类型是:String类型
R类型是:Integer
package com.itheima.sh.function_inter_02;
import java.util.function.Function;
/*
Function<T,R>转换接口
R apply(T t) 将参数T类型转换为R类型
需求:将字符串"123"转换为整数123 ---》将String类型转换为Integer
分析:
T类型是:String类型
R类型是:Integer
*/
public class Test05_Function {
public static void main(String[] args) {
//调用方法
/* show(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
// 需求:将字符串"123"转换为整数123
return Integer.parseInt(s);
}
}, "123");*/
//lambda : R apply(T t) 将参数T类型转换为R类型
// show((String str)->{return Integer.parseInt(str);},"123");
show(str-> Integer.parseInt(str),"123");
}
private static void show(Function<String,Integer> f,String s) {
//使用函数式接口对象f调用方法
Integer i = f.apply(s);//123
System.out.println("i = " + i);
}
}
图解:
小结:
1.Function<T,R>将前置类型T转换为后置类型R,我们使用lambda完成转换方法:
R apply(T t) 将参数T类型转换为R类型
2.Stream(必须掌握)
1.介绍
1.该接口位于java.util.stream 包下,使用需要导包
2.属于jdk8开始新的技术,表示流水线,和我们后面学习的IO流一点关系都没有
3.数据在流水线中保存
4.代码引入
需求:遍历集合
package com.itheima.sh.stream_03;
import java.util.ArrayList;
import java.util.Collections;
/*
Stream流水线引入:
1. 首先筛选所有姓张的人;
2. 然后筛选名字有三个字的人;
3. 最后进行对结果进行打印输出。
*/
public class StreamTest01 {
public static void main(String[] args) {
//1.创建集合对象
ArrayList<String> list = new ArrayList<>();
//2.添加数据
Collections.addAll(list, "张三", "张无忌", "周芷若", "赵敏", "小昭", "张三丰", "张翠山");
//3.创建一个新的集合保存姓张的人
ArrayList<String> zhangList = new ArrayList<>();
//4.遍历list集合取出每个数据
for (String name : list) {
//5.判断name是否以张开始
if(name.startsWith("张")){
//6.存储到zhangList中
zhangList.add(name);
}
}
// System.out.println("zhangList = " + zhangList);
// 2. 然后筛选名字有三个字的人;
//7.创建集合存储三个字的人
ArrayList<String> shortList = new ArrayList<>();
//8.遍历zhangList集合
for (String name : zhangList) {
//9.判断取出的数据name的长度是否是3
if(name.length() == 3){
shortList.add(name);
}
}
// 10. 最后进行对结果进行打印输出。
for (String name : shortList) {
System.out.println("name = " + name);
}
}
}
小结:通过上述案例我们发现使用之前的方式处理逻辑比较多的时候,遍历集合太麻烦了,不得不创建新的集合,不得不使用for循环。
使用Stream全新的语法遍历集合:
private static void method_2() {
//1.创建集合对象
ArrayList<String> list = new ArrayList<>();
//2.添加数据
Collections.addAll(list, "张三", "张无忌", "周芷若", "赵敏", "小昭", "张三丰", "张翠山");
/*
1. 首先筛选所有姓张的人;
2. 然后筛选名字有三个字的人;
3. 最后进行对结果进行打印输出。
*/
list.stream().filter(name->name.startsWith("张")).filter(name->name.length()==3).forEach(name-> System.out.println(name));
}
2.获取流方式
2.1使用集合获取
将集合中的数据放到Stream流水线中。
使用Collection中的默认方法:
default Stream<E> stream() 通过集合获取Stream流水线对象
代码演示:
package com.itheima.sh.stream_04;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.stream.Stream;
public class Test01 {
public static void main(String[] args) {
//创建集合对象
ArrayList<String> list = new ArrayList<>();
//获取流水线,使用Collection中的默认方法:default Stream<E> stream() 通过集合获取Stream流水线对象
Stream<String> stream = list.stream();
LinkedList<Integer> list2 = new LinkedList<>();
Stream<Integer> stream1 = list2.stream();
//创建HashSet集合
HashSet<String> hs = new HashSet<>();
Stream<String> stream2 = hs.stream();
}
}
2.2使用数组获取
使用Stream流水线中的方法:
static <T> Stream<T> of(T... values) 参数是可变参数,这里可以接收数组
代码演示:
package com.itheima.sh.stream_04;
import java.util.stream.Stream;
/*
将数组数据放到Stream流水线中
*/
public class Test02 {
public static void main(String[] args) {
//定义数组
String[] arr = {"abc","cde","abc"};
//将数组数据放到Stream流水线中
//static <T> Stream<T> of(T... values) 参数是可变参数,这里可以接收数组
Stream<String> s1 = Stream.of(arr);
//获取s1流水线中的数据个数
System.out.println(s1.count());//3
//定义整数数组
/* int[] arr2 = {10,20,30};
Stream<int[]> s2 = Stream.of(arr2);*/
//获取s2流水线中的数据个数
//这里直接将int类型的整个数组放到流水线中,如果将基本数据类型的数组放到流水线中,那么数组一定是包装类
// System.out.println(s2.count());//1
Integer[] arr3 = {10,20,30};
Stream<Integer> s3 = Stream.of(arr3);
System.out.println(s3.count());//3
}
}
小结:
1.将集合中的数据放到Stream流水线中,使用Collection中的默认方法
default Stream<E> stream() 通过集合获取Stream流水线对象
2.将数组中的数据放到流水线中使用Stream中静态方法:
static <T> Stream<T> of(T... values) 参数是可变参数,这里可以接收数组
注意:如果数组中的数据是基本数据类型,那么定义的数组类型要定义为包装类类型。
3.常用方法
- 终结方法:就是返回值不再是Stream ,就不能继续调用Stream中的方法了,就是不能链式编程了
- 非终结方法:返回值是Stream ,可以继续调用Stream中的方法,然后继续链式编程
1.forEach : 逐一处理
方法:
void forEach(Consumer<? super T> action) 对此流的每个元素执行操作。
参数:
action : 属于Consumer消费函数式接口类型,该接口中的消费方法: void accept(T t);
我们可以使用lambda
该方法属于终结方法,不能链式编程
代码演示:
package com.itheima.sh.stream_method_05;
import java.util.function.Consumer;
import java.util.stream.Stream;
/*
void forEach(Consumer<? super T> action) 对此流的每个元素执行操作。
参数:
action : 属于Consumer消费函数式接口类型,该接口中的消费方法: void accept(T t);
我们可以使用lambda
该方法属于终结方法,不能链式编程
*/
public class StreamDemo01 {
public static void main(String[] args) {
//1.获取流水线对象
Stream<Integer> s = Stream.of(10, 20, 30, 10);
//2.将上述流水线中的数据输出
/* s.forEach(new Consumer<Integer>() {
@Override
public void accept(Integer i) {
System.out.println(i);
}
});*/
// s.forEach((Integer i)->{System.out.println(i);});
s.forEach(i->System.out.println(i));
}
}
小结:
forEach()方法参数Consumer类型,我们使用lambda完成accept方法
2.filter:过滤
方法:
Stream<T> filter(Predicate<? super T> predicate);
参数:
predicate:属于Predicate判断函数式接口类型,该接口中的抽象方法 boolean test(T t);
我们在使用filter过滤方法的时候需要传递lambda给方法,然后进行过滤判断,如果test(T t)方法返回 true,说明满足过滤条件 ,将数据放到流水线,返回false,说明不满足条件,不放到流水线中
代码演示:
package com.itheima.sh.stream_method_05;
import java.util.stream.Stream;
/*
Stream<T> filter(Predicate<? super T> predicate);
参数:
predicate:属于Predicate判断函数式接口类型,该接口中的抽象方法 boolean test(T t);
我们在使用filter过滤方法的时候需要传递lambda给方法,然后进行过滤判断,如果test(T t)方法返回
true,说明满足过滤条件 ,将数据放到流水线,返回false,说明不满足条件,不放到流水线中
注意:filter属于非终结方法,可以实现链式编程
*/
public class StreamDemo02 {
public static void main(String[] args) {
//1.向流水线中存储数据
Stream<String> s = Stream.of("abc", "abch", "defg", "kajahj");
//2.使用s调用过滤方法筛选字符长度是4的字符串
//boolean test(T t);
// Stream<String> s1 = s.filter((String str) -> { return str.length() == 4;});
//3.输出s1中的内容 void accept(T t);
// s1.forEach(name-> System.out.println(name));
s.filter((String str) -> { return str.length() == 4;}).forEach(name-> System.out.println(name));
}
}
小结:
1.Stream filter(Predicate<? super T> predicate);表示过滤方法我们需要使用lambda完成参数的函数式接口Predicate中的判断方法 boolean test(T t);
2.使用Stream注意事项:
private static void method_2() {
//1.向流水线中存储数据
Stream<String> s = Stream.of("abc", "abch", "defg", "kajahj");
//s1流水线中的数据:abch defg
Stream<String> s1 = s.filter((String str) -> { return str.length() == 4;});
s1.forEach(name-> System.out.println(name));
//查看s中的数据
//java.lang.IllegalStateException: stream has already been operated upon or closed
/*
流水线对象只能消费一次(操作一次),不能操作多次,否则就会报异常,流水线关闭异常
*/
s.forEach(str-> System.out.println(str));
}
小结:一个流水线对象只能消费一次。
3.count:统计个数
long count(); 终结方法(不能链式编程) 表示统计流水线中的数据个数
//1.创建流水线对象
Stream<String> s = Stream.of("abc", "akja", "alala");
//求个数
long count = s.count();
System.out.println("count = " + count);
4.limit:取用前几个
Stream<T> limit(long n):获取Stream流对象中的前n个元素,返回一个新的Stream流对象.属于非终结方法,可以链式编程
//1.创建流水线对象
Stream<String> s = Stream.of("abc", "akja", "alala");
//Stream<T> limit(long n):获取Stream流对象中的前n个元素,返回一个新的Stream流对象.属于非终结方法,可以链式编程
//2表示获取流水线中的前2个数据
s.limit(2).forEach(str-> System.out.println(str));//"abc", "akja"
5.skip:跳过前几个
Stream<T> skip(long n): 跳过Stream流对象中的前n个元素,返回一个新的Stream流对象.属于非终结方法,可以链式编程
代码演示:
//1.创建流水线对象
Stream<String> s = Stream.of("abc", "akja", "alala");
//Stream<T> skip(long n): 跳过Stream流对象中的前n个元素,返回一个新的Stream流对象.属于非终结方法,可以链式编程
//跳过前2个元素 获取数据 "alala"
//这里的2表示跳过前2个元素
s.skip(2).forEach(str-> System.out.println("str = " + str));
6.映射:map
<R> Stream<R> map(Function<? super T, ? extends R> mapper);表示映射方法,将T类型转换为R类型,参数属于Function类型,属于函数式接口,转换方法:R apply(T t) 我们使用lambda完成转换
将原来的T类型圆转换为R类型及菱形。
需求:使用映射方法将老流中的字符串数据转换为新流中的整数。
package com.itheima.sh.stream_method_05;
import java.util.stream.Stream;
public class StreamDemo04 {
public static void main(String[] args) {
//1.创建老流
Stream<String> oldStream = Stream.of("123", "345", "456");
//2.通过map方法将上述老流中的数据映射为新的类型数据
/*
<R> Stream<R> map(Function<? super T, ? extends R> mapper);表示映射方法,将T类型转换为R类型,参数属于Function类型,
属于函数式接口,转换方法:R apply(T t) 我们使用lambda完成转换
*/
Stream<Integer> newStream = oldStream.map(str -> {
return Integer.parseInt(str);
});
//查看新的流水线中的数据
newStream.forEach(i-> System.out.println(i));
}
}
小结:
1.map方法表示映射方法,我们可以将T类型转换为R类型,使用lambda完成Function中的apply方法
7.concat:组合
static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b): 把参数列表中的两个Stream流对象a和b,合并成一个新的Stream流对象
在新的流水线中,a流的数据位于前面
代码演示:
package com.itheima.sh.stream_method_05;
import java.util.stream.Stream;
public class StreamDemo05 {
public static void main(String[] args) {
Stream<String> a = Stream.of("123", "345", "456");
Stream<String> b = Stream.of("柳岩", "杨幂", "冰冰");
//将上述a和b流中的数据拼接到一个新的流中
/*
static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b):
把参数列表中的两个Stream流对象a和b,合并成一个新的Stream流对象
在新的流水线中,a流的数据位于前面
*/
Stream<String> c = Stream.concat(a, b);
c.forEach(s -> System.out.println(s));
}
}
4.综合练习(课下必须完成)
package com.itheima.sh.stream_method_05;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
/*
现在有两个`ArrayList`集合存储队伍当中的多个成员姓名,要求使用Stream**依次**进行以下若干操作步骤:
1. 第一个队伍只要名字为3个字的成员姓名;
2. 第一个队伍筛选之后只要前3个人;
3. 第二个队伍只要姓张的成员姓名;
4. 第二个队伍筛选之后不要前2个人;
5. 将两个队伍合并为一个队伍;
6. 根据姓名创建`Person`对象;
7. 打印整个队伍的Person对象信息。
*/
public class Test01 {
public static void main(String[] args) {
List<String> one = new ArrayList<>();
one.add("迪丽热巴");
one.add("宋远桥");
one.add("苏星河");
one.add("老子");
one.add("庄子");
one.add("孙子");
one.add("洪七公");
one.add("宋小宝");
// 1. 第一个队伍只要名字为3个字的成员姓名;
// 2. 第一个队伍筛选之后只要前3个人; boolean test(T t);
//one.stream().filter(str->str.length()==3)筛选的数据:宋远桥 苏星河 洪七公 宋小宝
//最后结果:宋远桥 苏星河 洪七公
Stream<String> oneStream = one.stream().filter(str -> str.length() == 3).limit(3);
List<String> two = new ArrayList<>();
two.add("古力娜扎");
two.add("张无忌");
two.add("张三丰");
two.add("赵丽颖");
two.add("张二狗");
two.add("张天爱");
two.add("张三");
// 3. 第二个队伍只要姓张的成员姓名; boolean test(T t);
// 4. 第二个队伍筛选之后不要前2个人;
//two.stream().filter(name->name.startsWith("张")) 张无忌 张三丰 张二狗 张天爱 张三
//最后结果:张二狗 张天爱 张三
Stream<String> twoStream = two.stream().filter(name -> name.startsWith("张")).skip(2);
// 5. 将两个队伍合并为一个队伍;
// 6. 根据姓名创建`Person`对象;
// 7. 打印整个队伍的Person对象信息。
//Stream.concat(oneStream,twoStream) 结果是:宋远桥 苏星河 洪七公 张二狗 张天爱 张三
// Stream<String> concat = Stream.concat(oneStream, twoStream);
//6. 根据姓名创建`Person`对象; 是将流水线中的String类型转换为Person类型
//R apply(T t);
/*Stream.concat(oneStream, twoStream).map((String name) -> {
Person p = new Person(name);
return p;
});*/
//void accept(T t);
Stream.concat(oneStream, twoStream).map(name->new Person(name)).forEach(person-> System.out.println(person));
}
}
5.收集Stream结果(理解)
我们之前学习了如何将集合和数组中的数据放到Stream流水线中,那么使用Stream流水线操作数据很方便,最后操作完毕之后如果想将流水线中数据在放回集合或者数组中,怎么办呢?
1.将流水线中的数据放回到集合中
收集方法:使用Stream流水线中的方法:
R collect(Collector collector) 收集方法
参数:collector属于Collector接口类型,表示收集器。接口不能创建对象,我们使用工具类Collectors来获取收集器接口的对象
收集方法:
1)static <T> Collector toList() 返回一个 Collector ,将输入元素累加到一个新的 List 。
2)static <T> Collector toSet() 返回一个 Collector ,将输入元素累加到一个新的 Set 。
代码演示:
package com.itheima.sh.stream_collect_06;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/*
R collect(Collector collector) 收集方法
参数:collector属于Collector接口类型,表示收集器。接口不能创建对象,我们使用工具类Collectors来获取收集器接口的对象
收集方法:
1)static <T> Collector toList() 返回一个 Collector ,将输入元素累加到一个新的 List 。
2)static <T> Collector toSet() 返回一个 Collector ,将输入元素累加到一个新的 Set 。
*/
public class Demo01 {
public static void main(String[] args) {
//1.获取Stream对象
Stream<Integer> s = Stream.of(123, 345, 567);
//2.将s中的数据收集到List中
// List<Integer> list = s.collect(Collectors.toList());
// System.out.println("list = " + list);//list = [123, 345, 567]
//3.放到Set中
Set<Integer> set = s.collect(Collectors.toSet());
System.out.println("set = " + set);//set = [567, 345, 123]
}
}
小结:
将Stream中中数据收集到集合中步骤:
1.使用Stream中的方法:
R collect(Collector collector) 收集方法
2.使用工具类获取收集器即Collector对象
1)static <T> Collector toList() 返回一个 Collector ,将输入元素累加到一个新的 List 。
2)static <T> Collector toSet() 返回一个 Collector ,将输入元素累加到一个新的 Set 。
2.收集到数组中
Stream中的方法:
Object[] toArray();
代码演示:
package com.itheima.sh.stream_collect_06;
import java.util.Arrays;
import java.util.stream.Stream;
/*
Object[] toArray();
*/
public class Demo02 {
public static void main(String[] args) {
//1.创建Stream对象
Stream<Integer> s = Stream.of(123, 345, 567);
//2.放到数组中
Object[] arr = s.toArray();
System.out.println(Arrays.toString(arr));//[123, 345, 567]
}
}
3.Vector集合
1.属于List集合下面的子类,从jdk1.0就有了,从jdk1.2开始被ArrayList集合取代了。Vector多线程安全的,但是效率低
2.构造方法:
Vector() 构造一个空向量,使其内部数据数组的大小为 10,其标准容量增量为零。
3.代码演示:
package com.itheima.sh.vector_07;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;
public class VectorDemo01 {
public static void main(String[] args) {
method_2();
}
/*
Iterator 属于jdk1.2的,但是Vector集合属于jdk1.0的,那么在1.2之前怎么迭代Vector集合啊?
使用最早的迭代器Enumeration:
1. Enumeration<E>最早的迭代器接口
2.从jdk1.2后我们建议使用Iterator迭代器接口,而不是Enumeration,因为Iterator中多了一个remove删除方法
并且Iterator接口中的方法名字比Enumeration中的方法名字短:
boolean hasMoreElements() 测试此枚举是否包含更多的元素 相当于Iterator接口中的hasNext()
E nextElement() 获取迭代器数据 相当于Iterator接口中的next()
*/
private static void method_2() {
//1.创建Vector集合对象
Vector<String> v = new Vector<>();
//2.添加数据
v.add("柳岩");
v.add("大鹏");
v.add("小岳岳");
v.add("柳岩");
//3.根据集合对象调用方法获取Enumeration迭代器
//Enumeration<E> elements()返回此向量的组件的枚举。
Enumeration<String> en = v.elements();
while(en.hasMoreElements()){
//获取数据
String s = en.nextElement();
System.out.println("s = " + s);
}
}
private static void method_1() {
//1.创建Vector集合对象
Vector<String> v = new Vector<>();
//2.添加数据
v.add("柳岩");
v.add("大鹏");
v.add("小岳岳");
v.add("柳岩");
//3.迭代集合
//获取迭代器 可以使用Iterator迭代器迭代
Iterator<String> it = v.iterator();
while(it.hasNext()){
//获取数据
String s = it.next();
System.out.println("s = " + s);
}
}
}