List.fill(int)(method())在Java中是等价的吗?

时间:2016-01-29 13:10:42

标签: java list scala function

在Scala中,有一种方法看起来像这样。

List[(A, B)] = List.fill(n)(doSomething(arg))

我的问题是,是否有任何方法可以在Java中执行此操作,或者是否必须通过一系列冗长的for来完成此操作。

Java确实有Collections.fill,但它似乎没有按照我的意愿去做。

Scala实现如下:

def buyCoffee(cc: CreditCard): (Coffee, Charge) =
{
    val cup = new Coffee()
    (cup, Charge(cc, cup.price))
}
def buyCoffees(cc: CreditCard, n: Int): (List[Coffee], Charge) =
{
    val p: List[(Coffee, Charge)] = List.fill(n)(buyCoffee(cc))
}

对我来说,这在Java中似乎是不可行的,或者不是我所知道的Java或我迄今为止在文档中能够找到的内容。

此Scala代码可以在 Scala中的函数编程的第7页找到 作者:Paul Chiusana和RúnarBjarnason。

5 个答案:

答案 0 :(得分:6)

与Java 8相同:

  • 使用Stream生成序列
  • 对于序列的每个值,使用您想要的任何方法进行映射
  • 收集结果

示例:

List<Result> collect = IntStream.range(0, 5)
                      .mapToObj(i -> doSomething(i))
                      .collect(Collectors.toList());

public Result doSomething(Integer i) {
  return ...;
}

答案 1 :(得分:1)

我不确定,你在Java中试图“实现”的是什么,这似乎是“无法实现的”。

byCoffee

几乎没有你在scala中那么“长”。你看到的问题是什么?

Java不是一种函数式语言,尝试使用它就没有意义了:如果你想要功能,只需使用scala。

即使是人们为java8建议的解决方案,看起来也不漂亮(比这个更长),更难阅读,并且有微妙的问题(例如,.osg不能抛出异常,很多中间集合分配等。)

如果你正在编写java代码,最好使用惯用java,除非有合理的理由反对它。

答案 2 :(得分:1)

JEP for creating small collectionsthe issue is easier to read

它显示了几个习语,其中一个使用初始化程序。 Java 8版本的fill

import java.util.*;
import java.util.function.*;

public class j {
  public static <T> List<T> fill(int n, Function<Integer, T> f) {
    return Collections.unmodifiableList(new ArrayList<T>(n) {{
      for (int i = 0; i < n; i++) add(f.apply(i));
    }});
  }
  public static void main(String[] args) {
    List<Integer> values = fill(10, i -> 2 * i);
    for (int x : values) System.out.println(x);
  }
}

我还没有为其他方便寻找JEP,但很清楚这些API是他们的想法。

答案 3 :(得分:0)

格式简单:

ArrayList<Coffee> array = new ArrayList<Coffee>();
// array.add("Coffe Expresso") ...
CreditCard cc = new CreditCard("1234 4321 1234 4321");
for(Coffee obj : array){
   obj = new Coffee("Coffee - no sugar");
   buyCoffee(obj, cc);
}

public void buyCoffee(Coffee coffee, CreditCard cc){
    //...
}

答案 4 :(得分:0)

这肯定是回答这个问题的迂回方式,并且当然不能代替&#34; fill&#34;或其他功能编程方法。但是,它适用于Java中的此实现,这是此时的主要问题。

class Cafe
{

Results buyCoffee(CreditCard cc)
{
    Coffee cup = new Coffee();
    List<Results> myList = new ArrayList<Results>();

    myList.add(0, new Results(cup, new Charge(cc, cup.price)));
    return myList.get(0);
}


Map<List<Coffee>, Charge> buyCoffees(CreditCard cc, int n)
{
    List<Results> purchases = new ArrayList<Results>(n);
    for(int a = 0; a < n; a++)
    {
        Results r = new Results();
        r = buyCoffee(cc);
        purchases.add(r);
    }

    List<Coffee> coffeeList = new ArrayList<Coffee>(n);
    List<Charge> chargeList = new ArrayList<Charge>(n);

    for(int b = 0; b < n; b++)
    {
        Coffee c = purchases.get(b).ThisCoffee;
        Charge charge = purchases.get(b).ThisCharge;
        coffeeList.add(c);
        chargeList.add(charge);
    }

    Charge fc = new Charge();
    Double[] ChargeAmountArray = new Double[n];

    for(int d = 0; d < n; d++)
    {
        Double x = chargeList.get(d).amount;
        ChargeAmountArray[d] = x;
    }

    double sum = 0;

    for(Double d: ChargeAmountArray)
    {
        sum += d;           // 50.0@n=5, 100.0@n=10
    }

    Charge finalCharge = new Charge(cc, sum);

    Map<List<Coffee>, Charge> map;
    map = new HashMap<List<Coffee>, Charge>();
    map.put(coffeeList, finalCharge);
    return map;
}
}