1、Lambda练习
1.1、调用Collections.sort()方法,通过定制排序比较两个Employee(先按年龄比,年龄相同按照姓名比),使用Lambda作为参数传递
参考代码如下:
//tips:篇幅有限,省略了非核心代码
List<Employee> list = Arrays.asList(
new Employee("张三", 13),
new Employee("1李四", 11),
new Employee("王五", 12),
new Employee("2张三丰", 11));
Collections.sort(list, (e1,e2)->{
int num = Integer.compare(e1.getAge(), e2.getAge());
int num2 = num==0?e1.getName().compareTo(e2.getName()):num;
return num2;
});
for(Employee e:list){
System.out.println(e);
}
1.2、声明函数式接口,接口中声明抽象方法public String getValue(String str)
声明类Test02,类中编写方法使用接口作为参数,将一个字符串转成大写,并作为方法的返回值
再将一个字符串的第2个到第4个索引位置的元素进行截取
参考代码如下:
@FunctionalInterface
interface StringInter{
public String getValue(String str);
}
public class Test02 {
public static void main(String[] args) {
String str = "HelloWorld";
//需求1:将一个字符串转成大写
String s1 = fun(str, s->s.toUpperCase());
System.out.println(s1);
//需求2:将一个字符串的第2个和第4个索引位置进行截取子串
String s2 = fun(str, s->s.substring(2, 5));
System.out.println(s2);
}
//用于处理字符串
public static String fun(String s,StringInter i){
return i.getValue(s);
}
}
1.3、声明一个带两个泛型的函数式接口,泛型类型为<T,R>。T为参数,R为返回值
接口中声明对应抽象方法
在Test03类中声明方法,使用接口作为参数,计算两个long类型参数的和,计算两个long类型参数的乘积
参考代码如下:
interface Inter<T,R>{
R method(T t1,T t2);
}
public class Test03 {
public static void main(String[] args) {
long l1 = 10;
long l2 = 20;
//需求1:计算两个long类型参数的和
System.out.println(fun(l1, l2, (a,b)->a+b));
//需求2:计算两个long类型参数的乘积
System.out.println(fun(l1, l2, (a,b)->a*b));
}
//2个long类型进行处理
public static long fun(long l1, long l2, Inter<Long, Long> inter){
return inter.method(l1,l2);
}
}
1.4、String str = “赵丽颖,28”;
将字符串截取数字年龄部分,得到字符串;
将上一步的字符串转换成为int类型的数字;
将上一步的int数字加100,得到结果int数字。
参考代码如下:
@Test
public void test04() {
String str = "赵丽颖,28";
int result = fun(s->s.split(",")[1], s->Integer.parseInt(s), n -> n += 100, str);
System.out.println(result);
}
public int fun(Function<String,String> one,
Function<String,Integer> two,Function<Integer,Integer> three,String s){
return one.andThen(two).andThen(three).apply(s);
}
1.5、请按照格式“ 姓名:XX。性别:XX。 ”的格式将信息打印出来。
“迪丽热巴,女”,“古力娜扎,女”,“努尔哈赤,男”
参考代码如下:
@Test
public void test05() {
String[] arr = {"迪丽热巴,女","古力娜扎,女","努尔哈赤,男"};
printInfo(s->System.out.print("姓名:"+s.split(",")[0]),
s->System.out.println("。性别:"+s.split(",")[1]), arr);
}
public void printInfo(Consumer<String> one,Consumer<String> two,String[] arr){
for(String s:arr){
one.andThen(two).accept(s);
}
}
1.6、数组当中有多条“姓名+性别”的信息(“迪丽热巴,女”,“古力娜扎,女”,“努尔哈赤,男”,“赵丽颖,女”)
请通过 Predicate 接口的拼装将符合要求的字符串筛选到集合ArrayList 中,需要同时满足两个条件:
1)必须为女生;2)姓名为4个字
参考代码如下:
@Test
public void test06() {
String[] ary = {"迪丽热巴,女","古力娜扎,女","努尔哈赤,男","赵丽颖,女"};
List<String> list = filter(s->s.split(",")[1].equals("女"),
s->s.split(",")[0].length()==4, ary);
System.out.println(list);
}
public List<String> filter(Predicate<String> one,Predicate<String> two,String[] ary){
List<String> list = new ArrayList<String>();
for(String p:ary){
if(one.and(two).test(p)){
list.add(p.split(",")[0]);
}
}
return list;
}
2、Stream练习
2.1、现在有两个 ArrayList 集合存储队伍当中的多个成员姓名,
要求
- 第一个队伍只要名字为3个字的成员姓名,且只要前3个
- 第二个队伍只要姓张的成员姓名,且不要前面2个。
- 将两个队伍合并为一个队伍
- 根据姓名创建 Person 对象;存储到一个新集合中。
- 打印整个队伍的Person对象信息。
参考代码如下:
// 第一队
List<String> list1 = Arrays.asList("迪丽热巴","宋远桥","苏星河","石破天","石中玉","老子","庄子","洪七公");
// 第二队
List<String> list2 = Arrays.asList("古力娜扎","张无忌","赵丽颖","张三丰","尼古拉斯赵四","张天爱","张全蛋");
Stream<String> s1 = list1.stream().filter(s->s.length()==3).limit(3);
Stream<String> s2 = list2.stream().filter(s->s.startsWith("张")).skip(2);
Stream<String> stream = Stream.concat(s1, s2);
List<Person> list = stream.map(Person::new).collect(Collectors.toList());
list.forEach(System.out::println);
2.2、给定一个数字列表,返回一个由每个数的平方构成的列表
比如[1,2,3,4,5]返回[1,4,9,16,25]
参考代码如下:
List<Integer> list = Arrays.asList(1,2,3,4,5);
List<Integer> list2 = list.stream()
.map(a -> (int)Math.pow(a, 2))
.collect(Collectors.toList());
list2.forEach(System.out::println);
2.3、用map和reduce方法获取流中有多少个元素
参考代码如下:
List<Integer> list = Arrays.asList(1,2,3,4,5);
Optional<Integer> op = list.stream().map(a -> 1).reduce(Integer::sum);
System.out.println(op.get());
2.5、现有Trader类和Transaction类,类的定义如下:
//交易员类
class Trader{
private String name;
private String city;
//省略了构造、getters、setters和toString方法
}
//交易类
class Transaction{
private Trader trader;
private int year;
private int value;
//省略了构造、getters、setters和toString方法
}
需求:
- 找出2018年发生的所有交易,并按照交易额排序(由低到高)
- 交易员都在哪些不同的城市工作过
- 查找所有来自上海的交易员,并按照姓名排序
- 返回所有交易员的姓名字符串,按字母顺序排序
- 有没有交易员是在苏州工作的
- 打印生活在上海的交易员的所有交易额
- 所有交易中,最高的交易额是多少
- 找到交易额最小的交易
示例代码如下:
//1
List<Transaction> list = transactions.stream()
.filter(t -> t.getYear() == 2018)
.sorted((a,b) -> Integer.compare(a.getValue(), b.getValue()))
.collect(Collectors.toList());
list.forEach(System.out::println);
//2
List<String> citys = transactions.stream()
.map(t -> t.getTrader().getCity())
.distinct()
.collect(Collectors.toList());
citys.forEach(System.out::println);
//3
List<Trader> traders = transactions.stream()
.filter(t -> t.getTrader().getCity().equals("上海"))
.map(Transaction::getTrader)
.distinct()
.sorted((a,b) -> a.getName().compareTo(b.getName()))
.collect(Collectors.toList());
traders.forEach(System.out::println);
//4
List<String> names = transactions.stream()
.map(t -> t.getTrader().getName())
.distinct()
.sorted()
.collect(Collectors.toList());
names.forEach(System.out::println);
//5
boolean b = transactions.stream()
.map(t -> t.getTrader().getCity())
.anyMatch(c -> c.equals("苏州"));
System.out.println(b);
//6
Integer sumValue = transactions.stream()
.filter(t -> t.getTrader().getCity().equals("上海"))
.collect(Collectors.summingInt(Transaction::getValue));
System.out.println(sumValue);
//7
Optional<Transaction> op = transactions.stream()
.collect(Collectors.maxBy((t1, t2) -> Integer.compare(t1.getValue(), t2.getValue())));
System.out.println(op.get().getValue());
//8
Optional<Transaction> op = transactions.stream()
.min((t1,t2) -> Integer.compare(t1.getValue(), t2.getValue()));
System.out.println(op.get());