如何使用函数式编程来进行字符串操作?

时间:2014-02-08 22:43:48

标签: java functional-programming command-pattern lambdaj functional-java

我正在写一个函数,我基本上一遍又一遍地做同样的事情。我有下面列出的功能

public String buildGarmentsString(List<Garment> garments)
{
    StringBuilder garmentString = new StringBuilder(10000);
    for(int i=0;i<4;i++)
    {
        garmentString.append(this.garmentProductId(i,garments.get(i).getProductId()));
        garmentString.append(this.garmentColor(i,garments.get(i).getColor()));
        for(int j=0;j<garments.get(i).getSizes().size();j++)
        {
            //check xxsml
            if(garments.get(i).getSizes().get(j).getXxsml() >0)
            {
                garmentString.append(this.garmentSizes(i, Size.xxsml(),garments.get(i).getSizes().get(j).getXxsml()));

            }

            //check xsml
            if(garments.get(i).getSizes().get(j).getXsml() > 0)
            {
                garmentString.append(this.garmentSizes(i,Size.xsml(),garments.get(i).getSizes().get(j).getXsml()));
            }

            //check sml
            if(garments.get(i).getSizes().get(j).getSml() > 0)
            {
                garmentString.append(this.garmentSizes(i,Size.sml(),garments.get(i).getSizes().get(j).getSml()));
            }

            //check med
            if(garments.get(i).getSizes().get(j).getMed() > 0)
            {
                garmentString.append(this.garmentSizes(i,Size.med(),garments.get(i).getSizes().get(j).getMed()));
            }

            //check lrg
            if(garments.get(i).getSizes().get(j).getLrg() > 0)
            {
                garmentString.append(this.garmentSizes(i,Size.lrg(),garments.get(i).getSizes().get(j).getLrg()));
            }

            //check xlrg
            if(garments.get(i).getSizes().get(j).getXlg() > 0)
            {
                garmentString.append(this.garmentSizes(i,Size.xlg(),garments.get(i).getSizes().get(j).getXlg()));
            }

            //check xxlrg
            if(garments.get(i).getSizes().get(j).getXxl() >0)
            {
                garmentString.append(this.garmentSizes(i,Size.xxlg(),garments.get(i).getSizes().get(j).getXxl()));
            }

            //check xxxlrg
            if(garments.get(i).getSizes().get(j).getXxxl() >0)
            {
                garmentString.append(this.garmentSizes(i,Size.xxxlg(),garments.get(i).getSizes().get(j).getXxxl()));
            }


        }
    }
}

这是我的服装尺寸功能:

public String garmentSizes(int garmentNumber, String size,int numberToSend)
{
    String garmentSizes = "&garment["+garmentNumber+"][sizes]["+size+"]="+numberToSend;
    return garmentSizes;
}

我正试图弄清楚如何用更少的代码完成这项工作。我已经读过,通过函数式编程,您可以执行诸如将函数传递给其他函数的参数。在网上做了一些阅读之后,我想我想做这样的事情,但我不确定最好的方法是什么或者是什么。

我已经在堆栈溢出上做了一些阅读,我看到有人提到使用Command模式或FunctionalJava或LambdaJ来尝试在Java中使用这个特性。我已经阅读了两个库的文档,并阅读了关于命令模式的维基百科文章,但我仍然不确定如何使用其中任何一个来解决我的特定问题。有人可以向我解释一下吗?作为一个从未进行任何功能编程的人,这有点令人困惑。

3 个答案:

答案 0 :(得分:2)

  • 您可以使用局部变量来减少重复次数。例如说bySize = garments.get(i).getSizes().get(j)
  • 而不是size.getXxsml()size.getXsml()等。您可以使用枚举大小和循环大小。

整个事情看起来像是:

for(int j=0;j<garments.get(i).getSizes().size();j++) {
    bySize = garments.get(i).getSizes().get(j);
    for (Size s : Size.values()) {
        if (bySize.get(s) > 0)  {
            garmentString.append(garmentSizes(i, s, bySize.get(s)));
        }
    }
}

可以使用指向正确方法的开关或直接在枚举中实现bySize.get(s)方法,并且可以摆脱getXsml等方法。

答案 1 :(得分:1)

所有支票之间唯一不同的是:

getXxsml/xxsml, getXsml/xsml, getSml/sml, etc.

如果您可以将这些值(作为字符串)传递给某个上级方法,并且如果是 上层方法可以评估,即执行这些字符串,然后你可以只是 拥有这些值的数组并将该数组传递给该高级方法。

在Java中,你可以用反射做类似的事情 所有这些检查确实可以简化为更少 代码通过使用反射。

看看:
java.lang.Class
java.lang.reflect.Method
java.lang.reflect.Field
java.lang.reflect.Constructor
你会明白我的意思。

答案 2 :(得分:0)

从您的代码中可以看出,某些类具有以下方法:

 xxsml(), xsml(), sml(), med(), ..., xxxlg()

获取每种尺寸的金额(?)。

您可以更好地设计数据,如下所示:

  • 有一个“大小”类型,枚举所有大小(可以是枚举或某个属性为String key的类)
  • 有一个方法可以返回所有已知大小的List。
  • 将上述方法替换为amountFor(Size)这可以由Map<Size, Integer>
  • 支持

为了向后兼容,你可以改写旧方法:

int xxsml() {
    return amountFor(Size.XXSML);  // assuming you have a singleton instance
                                   // for each well known size
}

当然,在getGarmentString中,您将遍历所有已知大小的List:

for (Size sz : Size.getAllKnownSizes()) {
    if (garments.get(i).getSizes().get(j).amountFor(sz) > 0) {
          ... do whatever must be done here
    }
 }