Java流API将lambda表达式存储为变量

时间:2016-03-31 12:12:12

标签: java lambda java-8 java-stream

这个标题对我来说听起来很愚蠢,但必须至少有一些聪明的方法才能达到这样的效果,我不知道如何解释它。我需要使用sorted in stream API对数组进行排序。到目前为止,这是我的流:

Arrays.stream(sequence.split(" "))
        .mapToInt(Integer::parseInt)
        .boxed()
        .sorted((a, b) -> a.compareTo(b))
        .forEach(a -> System.out.print(a + " "));

现在我有两种不同的过程 - 升序和降序,我需要使用的排序在用户输入中指定。所以我想要做的就是切换2个案例:“升序”和“降序”以及分别存储lambda表达式的变量:

switch(command) {
    case "ascending": var = a.compareTo(b);
    case "descending": var = b.compareTo(a);
}

然后我的排序看起来像:

 .sorted((a, b) -> var)

我在参加的python课程中得到了这个想法。在那里可以将对象存储在变量中,从而使变量“可执行”。我意识到这个lambda不是一个对象,而是一个表达式,但我要问的是有什么聪明的方法可以实现这样的结果,或者我应该只有

if(var)

和每个排序顺序的两个不同的流。

3 个答案:

答案 0 :(得分:7)

您可以使用Comparator.naturalOrderComparator<Integer> comparator = youWantToHaveItReversed ? Comparator.reverseOrder(): Comparator.naturalOrder(); Arrays.stream(sequence.split(" ")) .map(Integer::valueOf) .sorted(comparator) .forEach(a -> System.out.print(a + " "));

切换
Protected Sub ShoesRepeater_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.RepeaterCommandEventArgs) Handles ShoesRepeater.ItemCommand
  Select Case e.CommandName  'This is the clicked button's CommandName
    Case "b1"
      'Do stuff for Button1
      'e.CommandArgument is the clicked button's CommandArgument
      'e.Item.FindControl("lblPrice") allows you to access other controls in this same Repeater item as the button that was clicked.
    Case "b2"
      'Do stuff for Button2
  End Select
  'There's a decent chance you'll want to rebind the grid when you're done.
End Sub

答案 1 :(得分:7)

这个问题根本不是愚蠢的。从更广泛的意义上回答:不幸的是,没有通用的解决方案。这是由于类型推断,它根据目标类型确定lambda表达式的一个特定类型。 (关于type inference的部分在这里可能会有所帮助,但不包括有关lambdas的所有细节。)

特别是像x -> y这样的lambda没有任何类型。所以没有办法写

GenericLambdaType function = x -> y;

以后使用function作为实际lambda x -> y的替代品。

例如,当您有两个功能,如

static void useF(Function<Integer, Boolean> f) { ... }
static void useP(Predicate<Integer> p) { ... }

你可以使用相同的lambda

来调用它们
useF(x -> true);
useP(x -> true);

但是没有办法&#34;存储&#34; x -> true lambda在某种程度上可以传递给两个函数 - 你只能将它存储在所需类型的引用中稍后:

Function<Integer, Boolean> f = x -> true;
Predicate<Integer>         p = x -> true;
useF(f);
useP(p);

对于您的特定情况,answer by Konstantin Yovkov已经显示了解决方案:您必须将其存储为Comparator<Integer>(忽略您在第一个时间内不需要lambda的事实地方...)

答案 2 :(得分:1)

在Lambdas中,您可以使用功能块 {{1}}