小编use*_*730的帖子

在Java中,为什么我不能使用lambda作为增强的for循环表达式?

假设我们有一个Iterator<Integer> iterator.因为Iterable是一个功能界面,我们可以写:

Iterable<Integer> iterable = () -> iterator;
Run Code Online (Sandbox Code Playgroud)

那么我们当然可以iterable用作增强的for循环表达式:

for (Integer i : iterable) foo(i);
Run Code Online (Sandbox Code Playgroud)

那么为什么呢

for (Integer i : () -> iterator) foo(i);
Run Code Online (Sandbox Code Playgroud)

不允许?(导致以下编译器错误:)

error: lambda expression not expected here
    for (Integer i : () -> iterator) foo(i);
                     ^
Run Code Online (Sandbox Code Playgroud)

使目标类型显式为

for (Integer i : (Iterable<Integer>) () -> iterator) foo(i);
Run Code Online (Sandbox Code Playgroud)

显然有效,但为什么编译器不能推断出λ-expression的目标类型?从表达式是λ表示法的事实来看,编译器不应该清楚目标类型不能是一个Array,因此必须是Iterable

这只是语言设计师的疏忽,还是我还缺少其他的东西?

java foreach lambda java-8

28
推荐指数
2
解决办法
3160
查看次数

在Java中,我如何有效和优雅地流式传输树节点的后代?

假设我们有一个由唯一Strings 标识的对象集合,以及一个Tree定义它们层次结构的类.该类使用Mapfrom节点(由其ID表示)到Collection其各自子节点的s来实现.

class Tree {
  private Map<String, Collection<String>> edges;

  // ...

  public Stream<String> descendants(String node) {
    // To be defined.
  }
}
Run Code Online (Sandbox Code Playgroud)

我想启用流式节点的后代.一个简单的解决方案是:

private Stream<String> children(String node) {
    return edges.getOrDefault(node, Collections.emptyList()).stream();
}

public Stream<String> descendants(String node) {
    return Stream.concat(
        Stream.of(node),
        children(node).flatMap(this::descendants)
    );
}
Run Code Online (Sandbox Code Playgroud)

在继续之前,我想对此解决方案做出以下断言.(我对这些是正确的吗?)

  1. Stream返回的descendants消耗资源(时间和内存) - 相对于树的大小 - 以与手动编码递归相同的复杂度顺序行走.特别地,表示迭代状态(Streams,Spliterators,...)的中间对象形成堆栈,因此在任何给定时间的存储器要求与树的深度具有相同的复杂度.

  2. 据我所知,只要我在执行终止操作Stream从返回descendants,根级别调用flatMap将导致所有包含Stream秒-一个用于每个(递归)呼叫descendants-被立即实现.因此,结果Stream …

java algorithm java-8 java-stream

18
推荐指数
2
解决办法
3060
查看次数

Objects.compare()方法的目的是什么?

Java 7引入了Objects包含" null-safe或null-tolerant"方法的类,包括compare(T, T, Comparator<T>).但我什么时候会用

Objects.compare(left, right, comparator);
Run Code Online (Sandbox Code Playgroud)

简单地打电话

comparator.compare(left, right);
Run Code Online (Sandbox Code Playgroud)

Objects.compare只有null-safe如果comparator也是如此,为什么我会包装比较调用?首先检查对象标识的优化似乎应该在比较器本身中完成.我能看到的行为中唯一真正的区别在于comparator.compare(left, right)抛出一个NullPointerException如果所有的comparator,left而且rightnull,而Objects.compare不是; 这似乎并不是一个重要的考虑因素,可以保证新的标准库方法.

我错过了一些明显的东西吗?

java java-7

11
推荐指数
1
解决办法
532
查看次数

仅在Elixir上导入函数时使用或指定arity

我正在研究Elixir,当我从模块导入函数时使用onlyexcept运算符时,我需要指定一个arity数.为什么?

例如

import :math, only: [sqrt: 1]
Run Code Online (Sandbox Code Playgroud)

要么

import :math, except: [sin: 1, cos: 1]
Run Code Online (Sandbox Code Playgroud)

functional-programming elixir

10
推荐指数
2
解决办法
354
查看次数

如何重置luigi任务状态?

目前,我有一堆排队的luigi任务,带有一个简单的依赖链(a -> b -> c -> d).d首先执行,a最后执行.a是被触发的任务.

所有目标除了a返回一个luigi.LocalTarget()对象并且具有一个通用luigi.Parameter()字符串(包含日期和时间).在luigi中央服务器上运行(已启用历史记录).

问题是,当我重新运行上述任务时a,luigi检查历史记录并查看之前是否运行过该特定任务,如果状态为DONE,则不执行任务(d在本例中)并且我不能有,改变字符串没有帮助(添加一个随机的微秒).如何强制执行任务?

python luigi snakebite

9
推荐指数
2
解决办法
4954
查看次数

我如何同时映射和group_by?

举个例子,假设我有collection很多对{first, second}.使用分组这些对

Enum.group_by(collection, fn {first, second} -> first end)
Run Code Online (Sandbox Code Playgroud)

将导致Map其键由传递的匿名函数确定.它的值是对的集合.但是,我希望它的值包含对的second元素.


一般来说,给定一个可枚举的,我想分组提供一个关键提取器一个值映射器,以便我可以确定将什么放入生成Map的值中.即,我想要类似的东西

map_group_by(
  collection,
  fn {_first, second} -> second end,
  fn {first, _second} -> first end
)
Run Code Online (Sandbox Code Playgroud)

collection分组之前将值映射到哪里,而键映射器仍然在原始元素上运行.

标准库中有这样的功能吗?如果没有,最实用的方法是什么?


我知道我可以做点什么

Enum.reduce(
  collection,
  %{},
  fn({key, value}, acc) -> Dict.update(acc, key, [value], &([value | &1])) end
)
Run Code Online (Sandbox Code Playgroud)

但这看起来很笨拙并且[value]先发制人地创建了名单(实际上是真的吗?).有没有更简洁有效的方法?

elixir

7
推荐指数
2
解决办法
4408
查看次数

在Julia中,如何在调用者提供的(超)类型的参数上正确调度方法?

我想定义一个函数f(x, t::Type),根据是否执行不同的行为isa(x, t).让我们说,b1(x)如果是,我想打电话,b2(x)否则.

我知道我可以在运行时进行动态检查,如下所示:

function f(x, t::Type)
  if isa(x, t)
    b1(x)
  else
    b2(x)
  end
end
Run Code Online (Sandbox Code Playgroud)

但是,有没有办法纯粹使用参数化方法调度?例如,如果我定义

f{T}(x::T, t::Type{T}) = b1(x)
f(x, t::Type) = b2(x)
Run Code Online (Sandbox Code Playgroud)

for f(1, Int)f(1.0, Int)调用正确的行为.但我希望这也适用于以下所有子类型t:

f(1, Number)
Run Code Online (Sandbox Code Playgroud)

这实际上是b2因为第一个签名f不匹配.有趣的是,f(x::Number, t::Type{Number}) = b1(x)在这种情况下会匹配.

我错过了一些明显的东西吗?

这显然是一个错误,并在0.4中修复.


问题:

  1. 为什么不f{T}(x::T, t::Type{T})匹配f(1, Number),即使T(Number)的类型替换匹配?

  2. 使用f{T2, T1 <: T2}(x::T1, t::Type{T2})或类似的东西不起作用,因为只有在关闭完整的静态参数列表后,所有静态参数才会出现在范围内.为什么?

  3. 使用动态方法是否会有任何性能损失?

  4. 如何将方法定义为内部函数,所以我可以绑定t到局部变量,如下所示: function f(x, …

julia

6
推荐指数
1
解决办法
352
查看次数

为什么算术运算符的参数类型默认为int?

我是F#的新手,我很惊讶地发现它的类型f x y = x + y实际上是int -> int -> int.显然,这是由于一些性能权衡.

为什么这实际上是必要的呢?为什么不直接推断类型'a -> 'a -> 'a或类似的类型?它似乎可以用于比较:类型g x y = x < yx:'a -> y:'a -> bool when 'a : comparison.为什么不对算术运算符呢?

编译器无法从调用站点静态推断出特定的基本类型,并从那里专门化泛型函数,如果失败则回退到某些动态调度?

这可能很明显,但我找不到任何好的资源.这种行为背后的原因是什么?

f#

6
推荐指数
1
解决办法
171
查看次数