什么是可变参数?如何使用可变参数?为什么学习Stream流?Stream流思想是什么?怎么Stream流?Stream流的三类方法?获取方法特点?中间方法特点?常见中间方法?终结方法特点?常见终结方法?


                          ==知识梳理==

Java进阶: 什么是可变参数?如何创建不可变集合?Steam三类方法是什么?获取流方法特点?流中间方法特点?终结流方法特点?_可变参数

                          ==重难点梳理==                  

Java进阶: 什么是可变参数?如何创建不可变集合?Steam三类方法是什么?获取流方法特点?流中间方法特点?终结流方法特点?_可变参数_02

                         ==今日目标==

1.能够了解什么是可变参数

2.能够了解如何去创建不可变集合

3.能够掌握Stream流的使用

                         ==知识点==

1.可变参数

2.Stream流

                         ==超详细讲义==

1.可变参数

1.1可变参数【了解】

(共4点)

1.什么是可变参数(个数)

可变参数就是参数个数不确定,个数范围[0-N]

2.如何使用可变参数

1.可变参数定义的可格式

修饰符 返回值类型 方法名(数据类型... 变量名) {  }

2.可变参数的基本使用

package com.itheima.variableparameter;

/**
* 需求:定义一个方法求N个数的和
* 可变参数实现
*/
public class MyVariableParameter2 {
public static void main(String[] args) {
// int [] arr = {1,2,3,4,5};
// System.out.println(arr);
int sum1 = getSum(1, 2, 3, 4, 5);
System.out.println(sum1);
}

public static int getSum(int number,int... arr) {
//System.out.println(arr);
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum = sum + arr[i];
}
return sum;
}
}

3.可变参数使用时的注意事项

如果一个方法有多个参数,包含可变参数,可变参数要放在最后

4.可变参数的应用场景

当参数类型确定,个数不确定时使用,可以使用可变参数

1.2创建不可变集合【了解】

(共三点)

1.什么是不可变集合

不可变集合,顾名思义就是说集合是不可被修改(增、删、改)的。集合的数据项在创建的时候提供,并且在整个生命周期中都不可改变

2.如何创建不可变集合(//回顾接口中的静态方法)



方法介绍



在List、Set、Map接口中,都存在of方法,可以创建一个不可变的集合



这个集合不能添加,不能删除,不能修改



但是可以结合集合的带参构造,实现集合的批量添加





在Map接口中,还有一个ofEntries方法可以提高代码的阅读性



首先会把键值对封装成一个Entry对象,再把这个Entry对象添加到集合当中



示例代码



package com.itheima.variableparameter;

import java.util.*;

public class MyVariableParameter4 {
public static void main(String[] args) {
// static <E> List<E> of(E…elements) 创建一个具有指定元素的List集合对象
//static <E> Set<E> of(E…elements) 创建一个具有指定元素的Set集合对象
//static <K , V> Map<K,V> of(E…elements)
// 创建一个具有指定元素的Map集合对象


//method1();
//method2();

//method3();

//method4();

}

private static void method4() {
Map<String, String> map = Map.ofEntries(
Map.entry("zhangsan", "江苏"),
Map.entry("lisi", "北京"));
System.out.println(map);
}

private static void method3() {
Map<String, String> map = Map.of("zhangsan", "江苏", "lisi", "北京", "wangwu", "天津");
System.out.println(map);
}

private static void method2() {
//传递的参数当中,不能存在重复的元素。
Set<String> set = Set.of("a", "b", "c", "d","a");
System.out.println(set);
}
private static Set<String> method5(){
Set<String> set = Set.of("a", "b", "c", "d");
return set;
}
private static void method1() {
/* List<String> list = List.of("a", "b", "c", "d");
System.out.println(list);*/
//list.add("Q");
//list.remove("a");
//list.set(0,"A");
//System.out.println(list);

/*ArrayList<String> list2 = new ArrayList<>();
list2.add("aaa");
list2.add("aaa");
list2.add("aaa");*/
//集合的批量添加。
//首先是通过调用List.of方法来创建一个不可变的集合,of方法的形参就是一个可变参数。
//再创建一个ArrayList集合,并把这个不可变的集合中所有的数据,都添加到ArrayList中。
ArrayList<String> list3 = new ArrayList<>(List.of("a", "b", "c", "d"));
System.out.println(list3);
}
}


2.Stream流

2.1Stream流-初体验【了解】

1.案例需求(对比)

按照下面的要求完成集合的创建和遍历


  • 创建一个集合,存储多个字符串元素
  • 把集合中所有以"张"开头的元素存储到一个新的集合
  • 把"张"开头的集合中的长度为3的元素存储到另一个新的集合
  • 遍历上一步得到的集合

2.为什么要使用流

Stream 对集合(Collection)对象功能的增强,专注于对集合对象进行各种非常便利、高效的操作,或者大批量数据操作 (bulk data operation)

示例代码

package com.itheima.streamdemo;

import java.util.ArrayList;
import java.util.List;

/**
* 体验Stream流
*
* 创建一个集合,存储多个字符串元素
* "张三丰","张无忌","张翠山","王二麻子","张良","谢广坤"
*
* 把集合中所有以"张"开头的元素存储到一个新的集合
*
*
* 把"张"开头的集合中的长度为3的元素存储到一个新的集合
* 遍历上一步得到的集合
*
*/
public class MyStream1 {
public static void main(String[] args) {
//集合的批量添加
ArrayList<String> list1 = new ArrayList<>(List.of("张三丰","张无忌","张翠山","王二麻子","张良","谢广坤"));
//list.add()

//遍历list1把以张开头的元素添加到list2中。
ArrayList<String> list2 = new ArrayList<>();
for (String s : list1) {
if(s.startsWith("张")){
list2.add(s);
}
}

//遍历list2集合,把其中长度为3的元素,再添加到list3中。
ArrayList<String> list3 = new ArrayList<>();
for (String s : list2) {
if(s.length() == 3){
list3.add(s);
}
}
for (String s : list3) {
System.out.println(s);
}

System.out.println("=======================");
//Stream流
list1.stream().filter(s->s.startsWith("张"))
.filter(s->s.length() == 3)
.forEach(s-> System.out.println(s));
}
}



2.2Stream流的思想特点【重点、难点】

1.Stream流的思想(静水器过滤)

Java进阶: 什么是可变参数?如何创建不可变集合?Steam三类方法是什么?获取流方法特点?流中间方法特点?终结流方法特点?_数据_03



Java进阶: 什么是可变参数?如何创建不可变集合?Steam三类方法是什么?获取流方法特点?流中间方法特点?终结流方法特点?_java_04



Stream流的三类方法


  • 获取Stream流
  • 中间方法
  • 终结方法

2.3 Stream流-获取方法 【重点】 

1.生成Stream流的方式


  • Collection体系集合
    使用默认方法stream()生成流, default Stream<E> stream()
  • Map体系集合
    把Map转成Set集合,间接的生成流
  • 数组
    通过Arrays中的静态方法stream生成流
  • 同种数据类型的多个数据
    通过Stream接口的静态方法of(T... values)生成流

代码演示

package com.itheima.streamdemo;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.stream.Stream;

/**
* Stream流的获取
单列集合 : 集合对象.stream();
双列集合 : 不能直接获取,需要间接获取
集合对象.keySet().stream();
集合对象.entrySet().stream();
数组 :
Arrays.stream(数组名);

同种数据类型的多个数据:

Stream.of(数据1,数据2,数据3......);

*/
public class MyStream2 {
public static void main(String[] args) {
//单列集合
//method1();


//双列集合
//method2();

//数组
//method3();

//同种数据类型的多个数据
//method4();

}

private static void method4() {
Stream.of(1,2,3,4,5,6,7,8).forEach(s-> System.out.println(s));
}

private static void method3() {
int [] arr = {1,2,3,4,5};
Arrays.stream(arr).forEach(s-> System.out.println(s));
}

private static void method2() {
HashMap<String,Integer> hm = new HashMap<>();
hm.put("zhangsan",23);
hm.put("lisi",24);
hm.put("wangwu",25);
hm.put("zhaoliu",26);
hm.put("qianqi",27);

//双列集合不能直接获取Stream流
//keySet
//先获取到所有的键
//再把这个Set集合中所有的键放到Stream流中
//hm.keySet().stream().forEach(s-> System.out.println(s));


//entrySet
//先获取到所有的键值对对象
//再把这个Set集合中所有的键值对对象放到Stream流中
hm.entrySet().stream().forEach(s-> System.out.println(s));
}

private static void method1() {
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");

// Stream<String> stream = list.stream();
// stream.forEach(s-> System.out.println(s));
list.stream().forEach(s-> System.out.println(s));
}
}

2.4Stream流-中间方法-filter【重点】

(共2点)

1.什么是中间方法

中间操作会返回一个新的流,一个流可以后面跟随零个或多个中间操作。

其目的主要是打开流,做出某种操作,然后会返回一个新的流,交给下一个操作使用

2.中间方法-filter

方法名

说明

Stream<T> filter(Predicate predicate)

用于对流中的数据进行过滤

filter代码演示

package com.itheima.streamdemo;

import java.util.ArrayList;
import java.util.function.Predicate;

/**
* Stream流的中间方法
*/
public class MyStream3 {
public static void main(String[] args) {
// Stream<T> filter•(Predicate predicate):过滤
// Predicate接口中的方法 boolean test•(T t):对给定的参数进行判断,返回一个布尔值

ArrayList<String> list = new ArrayList<>();
list.add("张三丰");
list.add("张无忌");
list.add("张翠山");
list.add("王二麻子");
list.add("张良");
list.add("谢广坤");

//filter方法获取流中的 每一个数据.
//而test方法中的s,就依次表示流中的每一个数据.
//我们只要在test方法中对s进行判断就可以了.
//如果判断的结果为true,则当前的数据留下
//如果判断的结果为false,则当前数据就不要.
// list.stream().filter(
// new Predicate<String>() {
// @Override
// public boolean test(String s) {
// boolean result = s.startsWith("张");
// return result;
// }
// }
// ).forEach(s-> System.out.println(s));


//因为Predicate接口中只有一个抽象方法test
//所以我们可以使用lambda表达式来简化
// list.stream().filter(
// (String s)->{
// boolean result = s.startsWith("张");
// return result;
// }
// ).forEach(s-> System.out.println(s));

list.stream().filter(s ->s.startsWith("张")).forEach(s-> System.out.println(s));


}
}



}

2.5 其他中间方法 (视频07)

其他中间方法

方法名

说明

Stream<T> limit(long maxSize)

返回此流中的元素组成的流,截取前指定参数个数的数据

Stream<T> skip(long n)

跳过指定参数个数的数据,返回由该流的剩余元素组成的流

static <T> Stream<T> concat(Stream a, Stream b)

合并a和b两个流为一个流

Stream<T> distinct()

返回由该流的不同元素(根据Object.equals(Object) )组成的流

package com.itheima.streamdemo;

import java.util.ArrayList;
import java.util.function.Predicate;

/**
* Stream流的中间方法
*/
public class MyStream3 {
public static void main(String[] args) {
// Stream<T> filter•(Predicate predicate):过滤
// Predicate接口中的方法 boolean test•(T t):对给定的参数进行判断,返回一个布尔值

ArrayList<String> list = new ArrayList<>();
list.add("张三丰");
list.add("张无忌");
list.add("张翠山");
list.add("王二麻子");
list.add("张良");
list.add("谢广坤");

//filter方法获取流中的 每一个数据.
//而test方法中的s,就依次表示流中的每一个数据.
//我们只要在test方法中对s进行判断就可以了.
//如果判断的结果为true,则当前的数据留下
//如果判断的结果为false,则当前数据就不要.
// list.stream().filter(
// new Predicate<String>() {
// @Override
// public boolean test(String s) {
// boolean result = s.startsWith("张");
// return result;
// }
// }
// ).forEach(s-> System.out.println(s));


//因为Predicate接口中只有一个抽象方法test
//所以我们可以使用lambda表达式来简化
// list.stream().filter(
// (String s)->{
// boolean result = s.startsWith("张");
// return result;
// }
// ).forEach(s-> System.out.println(s));

list.stream().filter(s ->s.startsWith("张")).forEach(s-> System.out.println(s));


}
}


2.6Stream流常见终结操作方法【重点】

1.什么终结操作

是指返回最终的结果的操作

2.终结操作的特点

一个流只能有一个终终操作,当这个操作执行后,流就被使用“光”了,无法再被操作

3.常用方法

方法名

说明

void forEach(Consumer action)

对此流的每个元素执行操作

long count()

返回此流中的元素数

代码演示

package com.itheima.streamdemo;

import java.util.ArrayList;
import java.util.function.Consumer;

/**
* Stream流的终结方法
*/
public class MyStream5 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("张三丰");
list.add("张无忌");
list.add("张翠山");
list.add("王二麻子");
list.add("张良");
list.add("谢广坤");

//method1(list);


// long count•():返回此流中的元素数
long count = list.stream().count();
System.out.println(count);


}

private static void method1(ArrayList<String> list) {
// void forEach•(Consumer action):对此流的每个元素执行操作
// Consumer接口中的方法 void accept•(T t):对给定的参数执行此操作
//在forEach方法的底层,会循环获取到流中的每一个数据.
//并循环调用accept方法,并把每一个数据传递给accept方法
//s就依次表示了流中的每一个数据.
//所以,我们只要在accept方法中,写上处理的业务逻辑就可以了.
list.stream().forEach(
new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
}
);

System.out.println("====================");

//lambda表达式的简化格式
//是因为Consumer接口中,只有一个accept方法
list.stream().forEach(
(String s)->{
System.out.println(s);
}
);
System.out.println("====================");

//lambda表达式还是可以进一步简化的.
list.stream().forEach(s->System.out.println(s));
}
}
}

2.7 Stream 流-不能直接修改数据源中的数据 【了解】

练习:

定义一个集合,并添加一些整数1,2,3,4,5,6,7,8,9,10 将集合中的奇数删除,只保留偶数。 遍历集合得到2,4,6,8,10

1.进一步理解Stream流

Stream它更像一个高级版本的 Iterator,不能直接修改数据源中的数据

package com.itheima.streamdemo;


import java.util.ArrayList;
import java.util.List;

/**
* Stream流的收集方法
* 练习:
* 定义一个集合,并添加一些整数1,2,3,4,5,6,7,8,9,10
* 将集合中的奇数删除,只保留偶数。
* 遍历集合得到2,4,6,8,10。
*/
public class MyStream6 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
list.add(i);
}

// list.stream().filter(
// (Integer i)->{
// return i % 2 == 0;
// }
// )
list.stream().filter(number -> number % 2 == 0).forEach(number -> System.out.println(number));
System.out.println("====================");

for (Integer integer : list) {
System.out.println(integer);
}


}
}

2.8Stream流的收集方法-toList和toSet【重点】

1.常用方法

方法名

说明

R collect(Collector collector)

把结果收集到集合中

2.工具类Collectors提供了具体的收集方式

方法名

说明

public static <T> Collector toList()

把元素收集到List集合中

public static <T> Collector toSet()

把元素收集到Set集合中

public static Collector toMap(Function keyMapper,Function valueMapper)

把元素收集到Map集合中

package com.itheima.streamdemo;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
* Stream流的收集方法
* 练习:
* 定义一个集合,并添加一些整数1,2,3,4,5,6,7,8,9,10
* 将集合中的奇数删除,只保留偶数。
* 遍历集合得到2,4,6,8,10。
*/
public class MyStream7 {
public static void main(String[] args) {
ArrayList<Integer> list1 = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
list1.add(i);
}

list1.add(10);
list1.add(10);
list1.add(10);
list1.add(10);
list1.add(10);

//filter负责过滤数据的.
//collect负责收集数据.
//获取流中剩余的数据,但是他不负责创建容器,也不负责把数据添加到容器中.
//Collectors.toList() : 在底层会创建一个List集合.并把所有的数据添加到List集合中.
List<Integer> list = list1.stream().filter(number -> number % 2 == 0)
.collect(Collectors.toList());

System.out.println(list);


Set<Integer> set = list1.stream().filter(number -> number % 2 == 0)
.collect(Collectors.toSet());
System.out.println(set);
}
}

2.9 Stream流的收集方法-toMap 【了解】

1.工具类Collectors提供了具体的收集方式

方法名

说明

public static Collector toMap(Function keyMapper,Function valueMapper)

把元素收集到Map集合中

package com.itheima.streamdemo;

import java.util.ArrayList;
import java.util.Map;
import java.util.stream.Collectors;

/**
* Stream流的收集方法
*
* 创建一个ArrayList集合,并添加以下字符串。字符串中前面是姓名,后面是年龄
* "zhangsan,23"
* "lisi,24"
* "wangwu,25"
* 保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
*/
public class MyStream8 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("zhangsan,23");
list.add("lisi,24");
list.add("wangwu,25");

Map<String, Integer> map = list.stream().filter(
s -> {
String[] split = s.split(",");
int age = Integer.parseInt(split[1]);
return age >= 24;
}

// collect方法只能获取到流中剩余的每一个数据.
//在底层不能创建容器,也不能把数据添加到容器当中

//Collectors.toMap 创建一个map集合并将数据添加到集合当中

// s 依次表示流中的每一个数据

//第一个lambda表达式就是如何获取到Map中的键
//第二个lambda表达式就是如何获取Map中的值
).collect(Collectors.toMap(
s -> s.split(",")[0],
s -> Integer.parseInt(s.split(",")[1]) ));

System.out.println(map);


}
}

2.10Stream流综合练习【重点】

  • 案例需求

    现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作

    • 男演员只要名字为3个字的前两人

    • 女演员只要姓林的,并且不要第一个

    • 把过滤后的男演员姓名和女演员姓名合并到一起

    • 把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据

    演员类Actor已经提供,里面有一个成员变量,一个带参构造方法,以及成员变量对应的get/set方法

  • 代码实现

    演员

    package com.itheima.streamdemo;
    public class Actor {
    private String name;

    public Actor() {
    }

    public Actor(String name) {
    this.name = name;
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    @Override
    public String toString() {
    return "Actor{" +
    "name='" + name + '\'' +
    '}';
    }

    }

    测试类

    package com.itheima.streamdemo;

    import java.util.ArrayList;
    import java.util.stream.Stream;

    /**
    * 现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作
    * 1.男演员只要名字为3个字的前两人
    * 2.女演员只要姓杨的,并且不要第一个
    * 3.把过滤后的男演员姓名和女演员姓名合并到一起
    * 4.把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据
    * 演员类Actor,里面有一个成员变量,一个带参构造方法,以及成员变量对应的get/set方法
    */
    public class MyStream9 {
    public static void main(String[] args) {
    ArrayList<String> manList = new ArrayList<>();
    manList.add("张国立");
    manList.add("张晋");
    manList.add("刘烨");
    manList.add("郑伊健");
    manList.add("徐峥");
    manList.add("王宝强");

    ArrayList<String> womanList = new ArrayList<>();
    womanList.add("郑爽");
    womanList.add("杨紫");
    womanList.add("关晓彤");
    womanList.add("张天爱");
    womanList.add("杨幂");
    womanList.add("赵丽颖");

    //男演员只要名字为3个字的前两人
    Stream<String> stream1 = manList.stream().filter(name -> name.length() == 3).limit(2);

    //女演员只要姓杨的,并且不要第一个
    Stream<String> stream2 = womanList.stream().filter(name -> name.startsWith("杨")).skip(1);


    Stream.concat(stream1,stream2).forEach(name -> {
    Actor actor = new Actor(name);
    System.out.println(actor);
    });
    }
    }

                             ==扩展练习==


day10-作业-Stream-可变参数

题目1[可变参数]

定义一个方法,可以求出任意个整数的和.然后在主方法中调用.

要求:

调用方法的时候,实参随便写就行,本题重点考察的是自定义方法的形参设计;

效果:

Java进阶: 什么是可变参数?如何创建不可变集合?Steam三类方法是什么?获取流方法特点?流中间方法特点?终结流方法特点?_java_05



(实参随便写,所以求和的结果不一样也行)

参考代码:

package day10.No_1;

public class Demo {
public static void main(String[] args) {
int sum=getSum(1,2);
System.out.println("两个整数的和"+sum);
int sum1 = getSum(1, 2, 3);
System.out.println("三个整数的和"+sum1);
int sum2 = getSum(1, 2, 333, 44);
System.out.println("四个整数的和"+sum2);
}

private static int getSum(int...arr) {
int sum=0;
for (int i : arr) {
sum+=i;
}return sum;
}
}

运行效果:

Java进阶: 什么是可变参数?如何创建不可变集合?Steam三类方法是什么?获取流方法特点?流中间方法特点?终结流方法特点?_可变参数_06



题目2[Stream]

随机生成10个10至20之间的随机数(数字不允许重复),使用Stream流的技术,找出大于15的元素并打印出来;

效果:

Java进阶: 什么是可变参数?如何创建不可变集合?Steam三类方法是什么?获取流方法特点?流中间方法特点?终结流方法特点?_数据_07



(随机数结果不要求一致,随机生成啥样就是啥样)

参考代码:

package day10.No_2;

import java.util.HashSet;
import java.util.Random;
import java.util.TreeSet;

public class Demo {
public static void main(String[] args) {
TreeSet<Integer>hs=new TreeSet<>() ;
while (true){//生成十个不重复的,所以当集合长度为10的时候,获取结束
Random r=new Random() ;
int i = r.nextInt(20-10+1)+10;//生成10-20的随机数
hs.add(i);
if (hs.size()==10){
break;
}
}
int count=1;
for (Integer h : hs) {
System.out.println("第"+count+"生成的为:"+h);
count++;
}
hs.stream().filter(i->{
return i>15;//过滤掉小于15的元素
}).forEach(s-> System.out.println("过滤小于十五之后为:"+s));
}
}

运行效果:

Java进阶: 什么是可变参数?如何创建不可变集合?Steam三类方法是什么?获取流方法特点?流中间方法特点?终结流方法特点?_数据_08



题目3[Stream]

定义集合HashSet<String>,添加以下数据: "王佳乐","张三丰","王思聪","张飞","刘晓敏","张靓颖","王敏"

(注意set集合保存的数据并不一定会和添加的顺序一致,所以需要先输出set集合中所有的元素查看原始顺序)

要求: 1:使用Stream流的filter()方法筛选集合中所有的“张”姓学员; 筛选后,获取前两个,并打印。 2:重新获取Stream流,用filter()方法筛选出所有的“王”姓学员; 筛选后,跳过第1个,打印剩余的人员。

效果:

Java进阶: 什么是可变参数?如何创建不可变集合?Steam三类方法是什么?获取流方法特点?流中间方法特点?终结流方法特点?_java_09



参考代码:

package day10.No_3;

import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

public class Demo {
public static void main(String[] args) {
HashSet<String> hs = new HashSet<>(Set.of("王佳乐", "张三丰", "王思聪", "张飞", "刘晓敏", "王敏"));
System.out.println("原始数据为:" + hs);
Set<String> set1 = hs.stream()
.filter(s -> s.startsWith("张"))//过滤不是姓张的
.limit(2)//只要前两个姓张的
.collect(Collectors.toSet());//收集姓张且只要两个
System.out.println("前两个姓张的为:" + set1);
Set<String> set2 = hs.stream()
.filter(s -> s.startsWith("王"))//过滤不是姓王的
.skip(1)//跳过第一个姓王的
.collect(Collectors.toSet());//收集姓王且过滤掉第一个
System.out.println("跳过第一个姓王的元素为:" + set2);
}
}

运行效果:

Java进阶: 什么是可变参数?如何创建不可变集合?Steam三类方法是什么?获取流方法特点?流中间方法特点?终结流方法特点?_数据_10



题目4[Stream]

定义main()方法,按以下顺序编写程序: 定义集合List<String>,添加以下数据: "王佳乐","张三丰","王思聪","张飞","刘晓敏","张靓颖","王敏"

要求: 1:筛选出所有的“张”姓学员; 2:筛选出所有的“王”姓学员; 3:将两个流合并为一个流后找出名字是3个字的名字数量

效果:

Java进阶: 什么是可变参数?如何创建不可变集合?Steam三类方法是什么?获取流方法特点?流中间方法特点?终结流方法特点?_java_11



参考代码:

package day10.No_4;

import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Demo {
public static void main(String[] args) {
HashSet<String> hs = new HashSet<>(Set.of("王佳乐", "张三丰", "王思聪", "张飞", "刘晓敏", "王敏", "张靓颖"));

System.out.println("原始数据为:" + hs);
Stream<String> stream = hs.stream()
.filter(s -> s.startsWith("张"));//过滤不是姓张的
Stream<String> stream1 = hs.stream()
.filter(s -> s.startsWith("王"));//过滤不是姓王的
Stream<String> concat = Stream.concat(stream, stream1);//合流,生成一个新的流
long count = concat.filter(s -> s.length() == 3).count();//姓张且姓王的个数
System.out.println("姓张和姓王名字为三个字的人共有:" + count);


}
}

运行效果:

Java进阶: 什么是可变参数?如何创建不可变集合?Steam三类方法是什么?获取流方法特点?流中间方法特点?终结流方法特点?_数据_12



题目5综合题[有难度]

本题综合单列集合,双列集合,键盘输入,Stream流操作

1.键盘录入3个学生信息,存储到学生对象(姓名,年龄).然后添加到ArrayList集合中. 2.键盘录入3个居住地信息,添加到另一个集合ArrayList; 3.把两个list集合中的数据收集到同一个map集合中,键是学生对对象,值是居住地址. 4.要求map集合中不能存在相同的学生信息.并按照学生年龄降序排列

5.使用Stream流输出集合中所有姓张的人信息;

效果:

Java进阶: 什么是可变参数?如何创建不可变集合?Steam三类方法是什么?获取流方法特点?流中间方法特点?终结流方法特点?_可变参数_13



参考代码:

类文件:

package day10.No_5;

import java.text.Collator;
import java.util.Locale;

public class Student implements Comparable<Student> {
private String name;
private int age;

public Student() {
}

public Student(String name, int age) {
this.name = name;
this.age = age;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

Student student = (Student) o;

if (age != student.age) return false;
return name != null ? name.equals(student.name) : student.name == null;
}

@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}

@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}

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;
}

@Override
public int compareTo(Student o) {
int i = this.age - o.age;
Collator instance = Collator.getInstance(Locale.CHINESE);
i = i == 0 ? instance.compare(this.name, o.name) : i;
return -i;//根据的是返回的正负进行排序的,所以正负能控制排序规则
}
}

测试类:

package day10.No_5;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Demo {
public static void main(String[] args) {
HashMap<Student, String> hm = new HashMap<>();
ArrayList<Student> keys = setStudent();//键盘录入学生信息,并存入集合
ArrayList<String>values=setJiguan();//键盘录入学生籍贯,并存人集合
for (int i = 0; i < keys.size(); i++) {//将获取到的key,value存入Map集合
Student key = keys.get(i);//获取每一个key
String value = values.get(i);//获取每一个值
hm.put(key, value);//将key和值存入集合
}
System.out.println("姓张的为:");
hm.entrySet().stream()
//过滤不是姓张的
.filter(s -> s.getKey().getName().startsWith("张"))
//输出学生信息和籍贯
.forEach(s-> System.out.println("信息:"+s.getKey()+"籍贯:"+s.getValue()));



}

private static ArrayList<String> setJiguan() {
ArrayList<String>list=new ArrayList<>() ;
Scanner sc=new Scanner(System.in);
for (int i = 1; i <= 3; i++) {//定义方法,获取三个学生籍贯存入集合,并返回
System.out.println("请输入第"+i+"位学生籍贯:");
String jiguan = sc.next();
list.add(jiguan);
}
return list;
}

public static ArrayList<Student> setStudent() {
ArrayList<Student> list = new ArrayList<>();
Scanner sc = new Scanner(System.in);
for (int i = 1; i <= 3; i++) {//定义方法,获取键盘录入的三个学生对象,并存人集合
System.out.println("请输入第" + i + "位学生姓名:");
String name = sc.next();
int age = 0;
while (true) {
sc = new Scanner(System.in);
System.out.println("请输入第" + i + "位学生年龄:");
try {
age = sc.nextInt();//捕获错误
break;
} catch (Exception e) {
System.out.println("必须为整数");
continue;
}
}
Student s = new Student(name, age);
list.add(s);
}
return list;
}
}

运行效果:

Java进阶: 什么是可变参数?如何创建不可变集合?Steam三类方法是什么?获取流方法特点?流中间方法特点?终结流方法特点?_可变参数_14