前期准备数据
public enum SkCategoryEnum {
CLOTHING(10,"服装类"),
ELECTRONICS(20,"数码类"),
SPORTS(30,"运动类"),
BOOKS(40,"图书类");
private Integer code;
private String name;
private SkCategoryEnum(Integer code, String name) {
this.code = code;
this.name = name;
}
}
public class Sku {
private Integer skuId;
private String skuName;
private Double skuPrice;
private Integer totalNum;
private Double totalPrice;
private Enum skCategory;
}
public class CarService {
private static List<Sku> carSkuList=new ArrayList<Sku>() {
{
add(new Sku(62329, "无人机", 4999.00, 1, 4999.00,
SkCategoryEnum.ELECTRONICS));
add(new Sku(62231, "vr一体机", 2299.00, 1, 2299.00,
SkCategoryEnum.ELECTRONICS));
add(new Sku(42131, "耐克冲锋衣", 499.00, 1, 499.00,
SkCategoryEnum.CLOTHING));
add(new Sku(55217, "牛仔裤", 100.00, 3, 300.00,
SkCategoryEnum.CLOTHING));
add(new Sku(62262, "衬衫", 399.00, 1, 399.00,
SkCategoryEnum.CLOTHING));
add(new Sku(44821, "耳机", 19.00, 1, 19.00,
SkCategoryEnum.ELECTRONICS));
add(new Sku(77466, "java编程", 199.00, 1, 199.00,
SkCategoryEnum.BOOKS));
}
};
public static List<Sku> getCartSkuList(){
return carSkuList;
}
}
需求1:根据商品类型筛选出数据
实现:略,for循环判断即可
需求迭代:根据一个布尔值,为true根据类型比较,false根据总价比较
实现
public List<Sku> filterSkusByCategory(List<Sku> carSkuList,SkCategoryEnum category,Double totalPrice,boolean categoryOrPrice){
List<Sku> result=new ArrayList<Sku>();
for (Sku sku : carSkuList) {
if(categoryOrPrice&&sku.getSkCategory().equals(category)) {
result.add(sku);
}else if(!categoryOrPrice && sku.getTotalPrice() >= totalPrice){
result.add(sku);
}
}
return result;
}
思考:那么怎么应对这种筛选功能的迭代呢?
/**
* sku选择谓词
* @author user
*
*/
public interface SkuPredicate {
boolean test(Sku sku);
}
/**
* 根据不同的sku判断标准,对sku列表进行过滤
* @param carSkuList
* @param predicate
* @return
*/
public List<Sku> filterSkus(List<Sku> carSkuList,SkuPredicate predicate){
List<Sku> result=new ArrayList<Sku>();
for (Sku sku : carSkuList) {
if(predicate.test(sku)) {
result.add(sku);
}
}
return result;
}
定义了一个SkuPredicate接口,用它的多个实现类来专门实现不同标准下,判断sku是否符合标准。
思考:如果创建多个SkuPredicate的实现类,但是它只会使用一次,可以使用匿名类
public static void main(String[] args) {
List<Sku> cartSkuList=CarService.getCartSkuList();
// 筛选总价大于1000的商品
CarService.filterSkus(cartSkuList, new SkuPredicate() {
public boolean test(Sku sku) {
if(sku.getTotalPrice()>1000) {
return true;
}
return false;
}
});
}
使用lambda来实现
public static void main(String[] args) {
List<Sku> cartSkuList=CarService.getCartSkuList();
CarService.filterSkus(cartSkuList,(Sku sku) -> sku.getTotalPrice() > 1000 );
}
可以看到使用lambda表达式来替代匿名函数,非常简洁
lambda表达式:
1、可以理解为一种匿名函数的代替
2、通过行为参数化传递代码
只有一个参数,小括号可以省略
image.png image.png image.png
函数式接口
1、接口只有一个抽象方法。
2、使用@FunctionalInterface,这个注解会校验是否符合函数式接口,也就第一条规则。
3、函数式接口的抽象方法签名:函数描述符
/**
* 文件处理函数式接口
* @author user
*
*/
@FunctionalInterface
public interface FileConsumer {
/**
* 函数式接口抽象方法
* @param fileContent 文件内容
*/
void fileHandler(String fileContent);
}
public class FileService {
public void fileHandle(String url,FileConsumer fileConsumer) {
//1、获取文件内容 略
// 2、调用FileConsumer类的处理方法
String fileContent="aaadd";
fileConsumer.fileHandler(fileContent);
}
public static void main(String[] args) {
FileService fileService=new FileService();
fileService.fileHandle("",fileContent -> System.out.println(fileContent));
}
}
常用的函数接口和使用
image.png所以上面的例子完全可以不用自己定义函数接口,而使用提供好的函数接口
public class FileService {
public void fileHandle2(String url,Consumer<String> consumer) {
//1、获取文件内容 略
// 2、调用FileConsumer类的处理方法
String fileContent="aaadd";
consumer.accept(fileContent);
}
public static void main(String[] args) {
FileService fileService=new FileService();
fileService.fileHandle2("",fileContent -> System.out.println(fileContent));
}
}
方法引用
调用特定方法的lambda表达式的一种快捷写法,可以让你重复的使用现有方法定义。并向lambda表达式义一样传递他们。
简单的说:调用一些特定的方法时,使用lambad表达式的快捷方式。
方法引用格式.png
有三种特定方法可以使用方法引用
1、指向静态方法的方法引用
public class FileService {
public void fileHandle2(String url,Consumer<String> consumer) {
//1、获取文件内容 略
// 2、调用FileConsumer类的处理方法
String fileContent="123";
consumer.accept(fileContent);
}
public static void main(String[] args) {
FileService fileService=new FileService();
fileService.fileHandle2("",fileContent -> Integer.parseInt(fileContent));
fileService.fileHandle2("",Integer::parseInt);
}
}
2、指向任意类型的实例方法
public class FileService {
public void fileHandle2(String url,Consumer<String> consumer) {
//1、获取文件内容 略
// 2、调用FileConsumer类的处理方法
String fileContent="123";
consumer.accept(fileContent);
}
public static void main(String[] args) {
FileService fileService=new FileService();
fileService.fileHandle2("",fileContent -> fileContent.length());
fileService.fileHandle2("",String::length);
}
}
指向任意类型的实例方法:这句话开始没看懂?什么叫实例方法?
百度了一下:实例方法就是当一个类创建了一个对象后,这个对象就可以调用该类的方法(对象方法)。
所以就好理解了,这里的fileContent已经被实例化了,所以可以使用方法引用
3、指向现有对象的实例方法的方法引用
public static void main(String[] args) {
FileService fileService=new FileService();
StringBuilder stringBuilder = new StringBuilder();
fileService.fileHandle2("",fileContent -> stringBuilder.append(fileContent));
fileService.fileHandle2("",stringBuilder::append);
}
网友评论