函数式编程
为什么需要函数式编程?
在一般的开发过程中我们的函数式编程都是通过匿名类进行传输函数。对于一个不会复用且不易命名或者不好放进某个具体的类中的临时方法。我们都可以使用匿名函数对象来进行处理。而 JDK8 对开发中比较常见的几种情况提供了一系列通用的函数对象。
四个主要的函数式对象
- Consumer : 描述消费泛型 T 对象且无返回值的匿名函数。
- Supplier : 描述有返回值为泛型 T 对象的匿名函数。
- Function : 描述输入泛型 T,返回泛型 R 的匿名函数。
- Predicate: 描述匿名的条件判断。
我们以订单以及订单中的商品举例来说明以下四种函数对象
订单类:
public class Order {
private List<Item> itemList;
public List<Item> getItemList() {
return itemList;
}
public void setItemList(List<Item> itemList) {
this.itemList = itemList;
}
}
商品类:
public class Item {
private String productName;
private Integer price;
public Item(){
}
public Item(String productName, Integer price) {
this.productName = productName;
this.price = price;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
@Override
public String toString() {
return "Item{" +
"productName='" + productName + '\'' +
", price=" + price +
'}';
}
}
为了方便生成测试订单,做了一个测试基类
public class AbstractTest {
protected static Order getTestOrder() {
Order order = new Order();
List<Item> itemList = new ArrayList<>();
Item item1 = new Item("键盘", 16);
Item item2 = new Item("鼠标", 32);
Item item3 = new Item("笔记本支架", 25);
itemList.add(item1);
itemList.add(item2);
itemList.add(item3);
order.setItemList(itemList);
return order;
}
}
Consumer
当你需要对某个泛型对象进行处理,并没有需要返回的值的话我们可以使用 Consumer 进行临时的处理。
以下我们通过消费一个订单,我们的处理逻辑是将订单中的所有商品都优惠 3 块钱。
public class ConsumerTest extends AbstractTest {
/**
* 调用accept方法接收order对象,具体操作交给匿名函数对象
*
* @param order
* @param orderConsumer
*/
public static void consume(Order order, Consumer<Item> orderConsumer) {
List<Item> itemList = order.getItemList();
if (itemList == null || itemList.isEmpty()) {
return;
}
for (Item item : itemList) {
orderConsumer.accept(item);
}
}
public static void main(String[] args) {
// 对订单中的商品进行优惠处理
consume(getTestOrder(), item -> item.setPrice(item.getPrice() - 3));
}
}
Consumer 对象还可以有 andThen()方法,继续传入 Consumer 对象进行链式处理。
Supplier
当我们需要返回特定泛型的匿名函数时,可以使用 Supplie 对象
在下面的例子中,我们通过 Supplier 中的逻辑返回每个商品的价格
public class SupplierTest extends AbstractTest{
/**
* 提取商品的价格
* @param item
* @param supplier
* @return
*/
public static Integer getPrice(Item item, Supplier<Integer> supplier) {
return supplier.get();
}
public static void main(String[] args) {
Order order = getTestOrder();
List<Item> itemList = order.getItemList();
if (itemList == null || itemList.isEmpty()) {
return;
}
List<Integer> priceList = new ArrayList<>();
for (Item item : itemList) {
priceList.add(getPrice(item, () -> item.getPrice()));
}
System.out.println(priceList.toString());
}
}
Function
当我们需要既对泛型参数进行处理,并返回另一个泛型参数时,可以使用 Funciton 这个函数对象。
在以下我们通过 Function 解析商品描述字符串并返回商品对象
public class FunctionTest extends AbstractTest {
/**
* 通过商品描述字符串解析并返回商品对象
*
* @param itemStr
* @param function
* @return
*/
public static Item getItem(String itemStr, Function<String, Item> function) {
return function.apply(itemStr);
}
public static void main(String[] args) {
List<String> itemStrList = new ArrayList<>();
itemStrList.add("苹果,22");
itemStrList.add("香蕉,33");
itemStrList.add("橘子,12");
List<Item> itemList = new ArrayList<>();
for (String itemStr : itemStrList) {
itemList.add(getItem(itemStr, s -> {
String[] split = itemStr.split(",");
return new Item(split[0], Integer.valueOf(split[1]));
}));
}
System.out.println(itemList);
}
}
在 Stream 流当中 Function 经常用来将参数对象转换为特定对象进行返回
Predicate
当我们需要将特定的判断表达式通过函数对象进行传入的时候,可以使用 Predicate 对象。
以下我们通过 Predicate 对象筛选出价格大于 30 的商品
public class PredicateTest extends AbstractTest {
public static void findExpensiveItem(Order order, Predicate<Item> predicate) {
List<Item> itemList = order.getItemList();
if (itemList == null || itemList.size() == 0) {
return;
}
for (Item item : itemList) {
if (predicate.test(item)) {
System.out.println(item);
}
}
}
public static void main(String[] args) {
// 找出价钱大于30的商品
findExpensiveItem(getTestOrder(), item -> item.getPrice() > 30);
}
}
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于