【问题标题】:Java integer cyclic iteration shorthandJava整数循环迭代速记
【发布时间】:2016-05-08 22:55:08
【问题描述】:

编码时我发现自己 经常做以下事情:

corner++; 
if(corner == 4) corner = 0;

有没有办法在一行中做到这一点?

在这个例子中角应该是 0, 1, 2, 3, 0, 1, 2, 3, 0....

【问题讨论】:

  • 您将来可能会发现modular arithmetic 会有所帮助。
  • 如果你发现自己经常做某事,你应该考虑提取方法而不是缩短代码(通常不太可读)

标签: java iteration


【解决方案1】:

使用余数。这是两条线,但很干净。

corner++;
corner %= 4;

【讨论】:

  • 有什么更高效的模式?老实说,我现在只是好奇。
  • @TheJohnMajor01:抱歉,这纯粹是过早的优化。它们都非常简短。
  • 更重要的是 5 个月后更容易理解和调试。
  • @Boann 首先,这根本不重要。但是具有常量的 mod 可以转换为 and op(如果您不能证明corner 始终为正,则编译器将需要更多),这可能会比分支。最重要的是:你真的不能做出这样的笼统陈述,因为周围有许多不同的 CPU 架构,具有一些非常不同的特性(一个分支在 SIMD 架构上非常昂贵,而 SIMD 架构恰好非常擅长做除法) )
  • @Morgen 不是 gcc/clang/etc。如果要求,也不会执行那种优化,尽管是在编译时。
【解决方案2】:

你可以这样做:

corner = ++corner == 4 ? 0 : corner;

如果您的 corner == 4 测试未通过,您可以将其他内容分配给 corner 变量。

【讨论】:

  • 虽然如此,但必须提及反对力求如此简洁,因为这可能会使一目了然的代码更难理解,使未来必须维护代码的编码人员更难。跨度>
  • @HovercraftFullOfEels 虽然您也是对的,但 OP 正在寻求简洁,而不是清晰; & 他会得到他想要的。
  • 既不简短也不清晰。这只是一团糟。 -1
  • 这也算不算复杂的代码,三元语句是一个很简单的结构。当然,(corner + 1) 会比 ++corner 更清晰,但这并不复杂。
  • 我的一些经验法则是: 1. 避免根据++xx++ 之间的差异而产生不同结果的代码,以及 2. 避免读取、修改值的代码并以非平凡的方式写在同一个语句中(如本例中的corner)。但是每个人都可能在这里有他的主观优先事项....
【解决方案3】:

您可以使用这种简短易读的行 (Demo):

corner = (corner + 1) % 4;

或者,甚至更短一点 (Demo):

corner = ++corner % 4;

【讨论】:

    【解决方案4】:

    我用:

    if (++corner == 4) corner = 0;
    

    【讨论】:

    • 我对此投了反对票,因为使用++ inline 太混乱了。当我阅读它时,很难将操作顺序保持在我的脑海中,并且很容易错过if 语句包含副作用。
    • @jpmc26 如果是corner++,我可以理解。但它是++corner,所以操作顺序是完全简单的从左到右。
    【解决方案5】:

    它不是那么显而易见,而是更快,因为除法的执行速度通常比任何按位运算都慢。

    corner = ++corner & 3;
    

    编辑:令人惊讶的是,我发现了一种更棒的骑自行车方式 - 使用轮班,它运行更快!

    corner = ++corner << 30 >>> 30;
    

    而且这个技巧只适用于 2 的任何幂。

    This benchmark 显示所有结果(虽然它是 javascript,而不是 java)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-30
      • 2011-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-27
      相关资源
      最近更新 更多