Solo  当前访客:2 开始使用

Lambda 表达式练习


Lambad表达式、函数式接口、带泛型函数式接口的使用

练习1

@RunWith(SpringRunner.class)
@SpringBootTest
public class PlatformApplicationTests {
	private Logger logger = LoggerFactory.getLogger(EntOrderRestController.class);

	@Test
	public void contextLoads() {
		//Predicate 判断真假
		Predicate<Integer> predicate = x -> x >= 175;
		Student student = new Student("王大锤", 180, 18);
		logger.info("王大锤有175吗?{}", predicate.test(student.getHeight()));

		//Consumer  消费消息
		Consumer<String> consumer = System.out::println;
		consumer.accept(student.getName());

		//Function 将T映射成R(转换功能)
		Function<Student, String> name = Student::getName;
		logger.info("姓名:" + name.apply(student));

		// Supplier  	生产消息
		Supplier<Integer> supplier = () -> Integer.valueOf(BigDecimal.TEN.toString());
		logger.info("生产消息:" + supplier.get());

		List<Student> students = new ArrayList<>(3);
		Student student1 = new Student("张三", 22, 175);
		Student student2 = new Student("李四", 40, 180);
		Student student3 = new Student("王五", 50, 185);
		students.add(student1);
		students.add(student2);
		students.add(student3);

		//UnaryOperator 一元操作  逻辑非(!)
		UnaryOperator<Boolean> unaryOperator = ugl -> !ugl;
		logger.info("一元操作返回值:" + unaryOperator.apply(true));

		//BinaryOperator   二元操作 求两个数的乘积(*)
		BinaryOperator<Integer> operator = (x, y) -> x * y;
		Integer apply = operator.apply(2, 3);
		logger.info("二元操作返回值:" + apply);

		//演示函数式接口
		test(() -> "你好,世界");

		//惰性求值:只描述 Stream,操作的结果也是 Stream,这样的操作称为惰性求值。
		//惰性求值可以像建造者模式一样链式使用,最后再使用及早求值得到最终结果。

		//及早求值:得到最终的结果而不是 Stream,这样的操作称为及早求值。

		//常用的流
		//collect(Collectors.toList())
		//将流转换为 list。还有 toSet(),toMap() 等。及早求值。
		List<Student> collect = Stream.of(student1, student2, student3).collect(Collectors.toList());
		logger.info("collect toList:"+collect);
		System.out.println(collect);

		//filter
		//顾名思义,起过滤筛选的作用。内部就是 Predicate 接口。惰性求值。
		//Predicate<Integer> predicate = x -> x >= 175;
		List<Student> collect1 = students.stream().filter(a -> a.getHeight() > 180).collect(Collectors.toList());
		logger.info("collect filter:"+collect1);

		//map
		//转换功能,内部就是 Function 接口。惰性求值
		List<Integer> collect2 = students.stream().map(Student::getAge).collect(Collectors.toList());
		logger.info("collect map:"+collect2);

		// flatMap
		//将多个 Stream 合并为一个 Stream。惰性求值
		List<Student> collect3 = Stream.of(students, asList(student)).flatMap(stu -> stu.stream()).collect(Collectors.toList());
		logger.info("collect flatMap:"+collect3);

		//max 和 min
		//我们经常会在集合中求最大或最小值,使用流就很方便。及早求值。
		Optional<Student> max = students.stream().max(comparing(Student::getAge));
		if (max.isPresent()) {
			logger.info("最大值:"+max.get());
		}
		Optional<Student> min = students.stream().min(comparing(stu -> stu.getAge()));
		if (min.isPresent()) {
			logger.info("最小值:"+min.get());
		}

		//count
		//统计功能,一般都是结合 filter 使用,因为先筛选出我们需要的再统计即可。及早求值
		long count = students.stream().filter(stu -> stu.getAge() < 40).count();
		logger.info("年龄小于40岁的人数是:"+count);

		// reduce
		//reduce 操作可以实现从一组值中生成一个值。在上述例子中用到的 count 、 min 和 max 方法,因为常用而被纳入标准库中。事实上,这些方法都是 reduce 操作。及早求值。
		Integer reduce = Stream.of(1, 2, 3, 4).reduce(0, (acc, x) -> acc+ x);
		logger.info("reduce:"+reduce);

		//转换成值
		//** 收集器,一种通用的、从流生成复杂值的结构。** 只要将它传给 collect 方法,所有
		//的流就都可以使用它了。标准类库已经提供了一些有用的收集器,以下示例代码中的收集器都是从 java.util.stream.Collectors 类中静态导入的。

		Clbum clbum1=new Clbum("一班",students);
		List<Student>students2=new ArrayList<>(students);
		students2.remove(1);
		Clbum clbum2=new Clbum("二班",students2);
		Stream<Clbum> clbumStream = Stream.of(clbum1, clbum2);

		System.out.println("一班平均年龄是:" + averageNumberOfStudent(students));
		//转换成块
		Map<Boolean,List<Student>>listMap=students.stream().
				collect(Collectors.partitioningBy(stu->stu.getAge()>40));
		logger.info("listMap:"+listMap);
		//分组
		Map<Integer,List<Student>>listMap1=students.stream().collect(Collectors.groupingBy(stu
				->stu.getAge()));
		logger.info("listMap1:"+listMap);
		//字符串拼接
		String names = students.stream().map(stu -> stu.getName()).collect(Collectors.joining(",", "[", "]"));
		logger.info("names:"+names);
	}

	 private  double averageNumberOfStudent(List<Student> students) {
		return students.stream().collect(averagingInt(Student::getAge));
	}



	public interface Worker {
		String Work();

	}

	public void test(Worker worker) {
		worker.Work();
	}

	class Student {
		public String name;
		public Integer height;
		public Integer age;

		public Student() {
		}

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

		public String getName() {
			return name;
		}

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

		public Integer getHeight() {
			return height;
		}

		public void setHeight(Integer height) {
			this.height = height;
		}

		public Integer getAge() {
			return age;
		}

		public void setAge(Integer age) {
			this.age = age;
		}
	}

	class Clbum{
		public String name;
		public List<Student> student;

		public Clbum() {
		}

		public Clbum(String name, List<Student> student) {
			this.name = name;
			this.student = student;
		}

		public String getName() {
			return name;
		}

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

		public List<Student> getStudent() {
			return student;
		}

		public void setStudent(List<Student> student) {
			this.student = student;
		}
	}

}

练习2

@SpringBootTest
class LambdaTest {
    List<Employee> emps = Arrays.asList(
            new Employee(101, "张三", 18, 9999.99),
            new Employee(102, "李四", 59, 6666.66),
            new Employee(103, "王五", 28, 3333.33),
            new Employee(104, "赵六", 18, 7777.77),
            new Employee(105, "田七", 38, 5555.55)
    );


    @Test
    public void createTest() {
        //根据年龄排序,年龄相同根据薪资
        Collections.sort(emps, (x, y) -> {
            if (x.getAge() == y.getAge()) {
                return Double.compare(x.getSalary(), y.getSalary());
            } else {
                return Integer.compare(x.getAge(), y.getAge());
            }
        });
        System.out.println("emps=" + emps);


    }

    /**
     * 要求:
     * ①声明函数式接口,接口中声明抽象方法,public String getValue();
     * ②声明测试类,在类中编写方法使用接口作为参数,将每一个字符品转换成大写,并作为方法的返回值
     * ③再将一个字符串的第2个和第4个索引位置进行截取子串
     */
    @Test
    public void test2() {
        String str = "admin NBA Cba";
        String valueF = getValueF(str,
                x -> x.substring(0, 1).toUpperCase() + x.substring(1)

        );
        getValueJ(str, x -> (x.substring(0, 1).toUpperCase() + x.substring(1)));
        getValueJ(str, (x) -> (x.substring(0, 1)));
        System.out.println("valueF = " + valueF);

        String valueF2 = getValueF(str,
                x -> x.substring(1, 3)
        );
        System.out.println("valueF2 = " + valueF2);

    }

        public String getValueJ(String param, MyFunction1 function) {
            return function.getValue(param);
        }

        public String getValueF(String str, MyFunction1 string2UpChar) {
            return string2UpChar.getValue(str);
        }

    /**
     * 要求:
     * ①声明一个带两个泛型的函数式接口,泛型类型为<T,R> T为参数,R为返回值
     * ②接口中声明对应抽象方法
     * ③在测试类中声明方法,使得接口作为参数,计算两个long型参数的乘积
     */
    @Test
    public void test3() {
        String calc = calc1(10L, 3L,
                (a, b) -> new BigDecimal(a).multiply(new BigDecimal(b)).toString()
        );
        System.out.println("calc = " + calc);
    }


    public String calc1(Long l1, long l2, MyFunction3<Long, String> function3) {
        return function3.calc(l1, l2);
    }

}

    @FunctionalInterface
    interface MyFunction1 {
        String getValue(String str);
    }

    @FunctionalInterface
    interface MyFunction3<P, R> {
        R calc(P t1, P t2);
    }


@Data
@Builder
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
class Employee {

    private int id;
    private String name;
    private int age;
    private double salary;

}

0 0