Chinaunix首页 | 论坛 | 博客
  • 博客访问: 101940
  • 博文数量: 18
  • 博客积分: 681
  • 博客等级: 中士
  • 技术积分: 295
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-17 13:33
文章分类
文章存档

2012年(8)

2011年(10)

分类: Java

2012-05-24 20:07:13

使用Java写的几个列表处理函数,有以下几个函数:
  • filter,过滤,根据一个谓词判断过滤列表;
  • reverse,把一个列表反转;
  • map,把一个列表元素映射按照一定规则转换成另外一个列表;
  • accumulate,累“加”,加可定制;
  • foldLeft,向左折叠,同accumulate;
  • foldRight,向右折叠。
代码如下:

点击(此处)折叠或打开

  1. package listutils;

  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import java.util.ListIterator;


  5. /**
  6.  * 列表工具

  7.  *
  8.  * 函数式编程中使用的一些常用列表函数
  9.  *
  10.  * @author lingyun.yang
  11.  */
  12. public class ListUtils {
  13.     
  14.     /**
  15.      * 谓词接口
  16.      * @param 参数类型
  17.      */
  18.     public interface Predicator<T> {
  19.         /**
  20.          * 谓词判断
  21.          * @param e        输入参数
  22.          * @return        truefalse
  23.          */
  24.         boolean predicate(T e);
  25.     }
  26.     
  27.     /**
  28.      * 映射器接口
  29.      * @param 映射前参数类型
  30.      * @param 映射后参数类型
  31.      */
  32.     public interface Mapper<T1, T2> {
  33.         /**
  34.          * @param e        输入参数
  35.          * @return        映射后结果
  36.          */
  37.         T2 map(T1 e);
  38.     }
  39.     
  40.     /**
  41.      * 二元操作符,在accumulate中使用
  42.      * @param     参数类型
  43.      */
  44.     public interface BinaryOperator<T> {
  45.         /**
  46.          * @param e1    输入参数
  47.          * @param e2    输入参数
  48.          * @return        两个输入参数之和
  49.          */
  50.         T operate(T e1, T e2);
  51.     }
  52.     
  53.     /**
  54.      * 列表过滤
  55.      *
  56.      * @param             列表元素类型
  57.      * @param sequence        输入列表
  58.      * @param predicate     谓词
  59.      * @return                过滤后的列表
  60.      *
  61.      * 遍历列表,当列表元素的判断为真时就留下该元素
  62.      */
  63.     public static <T> List<T> filter(List<T> sequence, Predicator<T> predicate) {
  64.         List<T> outSeq = new ArrayList<T>();
  65.         for (T e : sequence) {
  66.             if (predicate.predicate(e)) {
  67.                 outSeq.add(e);
  68.             }
  69.         }
  70.         return outSeq;
  71.     }
  72.     
  73.     /**
  74.      * 反转一个列表
  75.      *
  76.      * @param         列表元素 类型
  77.      * @param sequence    输入列表
  78.      * @return            反转过后的列表
  79.      */
  80.     public static <T> List<T> reverse(List<T> sequence) {
  81.         List<T> outSeq = new ArrayList<T>();
  82.         ListIterator<T> it = sequence.listIterator(sequence.size());
  83.         while (it.hasPrevious()) {
  84.             outSeq.add(it.previous());
  85.         }
  86.         return outSeq;
  87.     }
  88.     
  89.     /**
  90.      * 列表映射
  91.      *
  92.      * @param         输入列表元素类型
  93.      * @param         输出列表元素类型
  94.      * @param sequence    输入列表
  95.      * @param map        映射函数,使用接口实现
  96.      * @return            映射后的列表
  97.      *
  98.      * 遍历列表,映射每个元素
  99.      */
  100.     public static <T1, T2> List<T2> map(List<T1> sequence, ListUtils.Mapper<T1, T2> map) {
  101.         List<T2> outSeq = new ArrayList<T2>();
  102.         for (T1 e: sequence) {
  103.             outSeq.add(map.map(e));
  104.         }
  105.         return outSeq;
  106.     }
  107.     
  108.     
  109.     /**
  110.      * 列表累加
  111.      *
  112.      * @param         列表元素类型
  113.      * @param sequence    列表
  114.      * @param initial    初始值
  115.      * @param op        二元操作符
  116.      * @return            列表综合
  117.      * @note            同foldLeft
  118.      */
  119.     public static <T> T accumulate(List<T> sequence, T initial, ListUtils.BinaryOperator<T> op) {
  120.         T sum = initial;
  121.         for (T e : sequence) {
  122.             sum = op.operate(sum, e);
  123.         }
  124.         return sum;    
  125.     }
  126.     
  127.     /**
  128.      * 列表左折叠,即从左往右遍历
  129.      *
  130.      * @param         列表元素类型
  131.      * @param op        二元操作符
  132.      * @param initial    初始值
  133.      * @param sequence    列表
  134.      * @return            列表综合值
  135.      * @note            同accumulate,建议使用accumulate本函数
  136.      */
  137.     public static <T> T foldLeft(List<T> sequence, T initial, ListUtils.BinaryOperator<T> op) {
  138.         T sum = initial;
  139.         for (T e : sequence) {
  140.             sum = op.operate(sum, e);
  141.         }
  142.         return sum;
  143.     }
  144.     
  145.     /**
  146.      * 列表右折叠,即从右往左遍历
  147.      *
  148.      * @param         列表元素类型
  149.      * @param op        操作符
  150.      * @param initial    初始值
  151.      * @param sequence    列表
  152.      * @return            列表综合值
  153.      */
  154.     public static <T> T foldRight(List<T> sequence, T initial, ListUtils.BinaryOperator<T> op) {
  155.         T sum = initial;
  156.         ListIterator<T> it = sequence.listIterator(sequence.size());
  157.         while (it.hasPrevious()) {
  158.             sum = op.operate(it.previous(), sum);
  159.         }
  160.         return sum;
  161.     }
  162. }
测试代码:

点击(此处)折叠或打开

  1. package listutils;

  2. import java.util.ArrayList;
  3. import java.util.List;

  4. public class ListUtilsTest {

  5.     private static final List<Integer> inList = new ArrayList<Integer>();

  6.     public static void main(String[] args) {
  7.         
  8.         inList.add(1);
  9.         inList.add(2);
  10.         inList.add(3);
  11.         inList.add(4);

  12.         testFilter();
  13.         testMap();
  14.         testAccumulate();
  15.         testReverse();
  16.         testFoldRight();
  17.     }

  18.     public static void testFilter() {
  19.         // 列表过滤器,过滤掉所有大于1的元素
  20.         ListUtils.Predicator<Integer> predicator = new ListUtils.Predicator<Integer>() {
  21.             @Override
  22.             public boolean predicate(Integer e) {
  23.                 return e > 1;
  24.             }
  25.         };

  26.         List<Integer> outList = ListUtils.filter(inList, predicator);
  27.         System.out.println(inList);
  28.         System.out.println(outList);
  29.     }

  30.     public static void testMap() {
  31.         // 列表映射,映射成相反数
  32.         List<Integer> outList = ListUtils.map(inList,
  33.                 new ListUtils.Mapper<Integer, Integer>() {
  34.                     @Override
  35.                     public Integer map(Integer e) {
  36.                         return e * -1;
  37.                     }
  38.                 });

  39.         System.out.println(inList);
  40.         System.out.println(outList);
  41.     }

  42.     public static void testReverse() {
  43.         System.out.println(ListUtils.reverse(inList));
  44.     }
  45.     
  46.     public static void testAccumulate() {
  47.         
  48.         // 列表累加
  49.         Integer sum = ListUtils.accumulate(inList, 0, new ListUtils.BinaryOperator<Integer>() {

  50.             @Override
  51.             public Integer operate(Integer e1, Integer e2) {
  52.                 return e1 + e2;
  53.             }
  54.         });
  55.         System.out.println(sum);
  56.     }
  57.     
  58.     public static void testFoldRight() {
  59.         
  60.         // 加操作符
  61.         ListUtils.BinaryOperator<Integer> adder = new ListUtils.BinaryOperator<Integer>() {
  62.             @Override
  63.             public Integer operate(Integer e1, Integer e2) {
  64.                 return e1 + e2;
  65.             }
  66.         };
  67.         
  68.         // 列表累加
  69.         Integer sum = ListUtils.foldLeft(inList, 0, adder);
  70.         // 反向累加
  71.         Integer reversedSum = ListUtils.foldLeft(ListUtils.reverse(inList), 0,
  72.             adder);
  73.         
  74.         System.out.println(sum);
  75.         System.out.println(reversedSum);
  76.         
  77.         // 除操作符
  78.         ListUtils.BinaryOperator<Double> diver = new ListUtils.BinaryOperator<Double>() {
  79.             @Override
  80.             public Double operate(Double e1, Double e2) {
  81.                 return e1 / e2;
  82.             }
  83.         };
  84.         
  85.         List<Double> newInList = ListUtils.map(inList, new ListUtils.Mapper<Integer, Double>() {
  86.             @Override
  87.             public Double map(Integer e) {
  88.                 return e.doubleValue();
  89.             }
  90.         });
  91.         
  92.         Double div = ListUtils.foldLeft(newInList, 1.0, diver);
  93.         Double reverseDiv = ListUtils.foldRight(newInList, 1.0, diver);
  94.         System.out.println(div);
  95.         System.out.println(reverseDiv);
  96.     }

  97. }

阅读(2399) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~