【问题标题】:Extracting integers from a HashSet<Double>从 HashSet<Double> 中提取整数
【发布时间】:2020-12-13 08:19:08
【问题描述】:

我有一个HashSet&lt;Double&gt;,我想从中提取整数元素,即小数点后全为零的元素。有这样做的标准方法吗?我可以做一些迂回的事情,例如:给定一个双精度 x,我可以查看小数点后的所有值,看看它们是否都为零,但这似乎很复杂。

【问题讨论】:

  • 你将不得不做一些迂回的事情,因为对于 JVM,任何双精度值都是双精度值,它不会检查这样的值是否足够接近整数。
  • 请注意,double 的大数字没有足够的精度来确定是否需要整数。
  • 你也应该决定一个公差。 2.000_000_000_000_000_4 可能是不准确的 2,因此您可能希望将其视为一个整数,具体取决于您的情况。

标签: java hashset


【解决方案1】:

您可以将它们转换为整数并将转换后的值与原始值相等

double d = 1.5;
if((int)d==d) // integer
else // not integer

【讨论】:

  • 它只在int范围内有效。我想 2_147_483_649.0(也写成 2.147483649E9)算作一个整数,但你的 if 条件评估为假。
  • 是的。但是您可以对 BigDecimal 执行相同操作并将其与 bigDecimal.toBigInteger() 进行比较
【解决方案2】:

我猜你喜欢整数而不是双精度数的最终结果。例如。 7 而不是 7.0。

所以试试这个:

    Set<Double> set = new HashSet<>();
    set.add(6.4);
    set.add(10.44);
    set.add(7.0);

    Set<Integer> filtered = set.stream()
            .filter(item -> Math.floor(item) == item)
            .map(Double::intValue)
            .collect(Collectors.toSet());

    System.out.println(filtered);

【讨论】:

    【解决方案3】:

    你可以这样做:

    HashSet<Double> hd = new HashSet<> ();
    hd.add (3.5);
    hd.add (2.0);
    hd.add (3.444);
    hd.add (-1.0);
    Set<Double> filtered = hd.stream()
                             .filter (x -> (int)(double)x == x)
                             .collect (Collectors.toSet());
    System.out.println (filtered);
    

    输出:

    [2.0, -1.0]
    

    您首先必须将Double 转换为double,然后再将其转换为int。如果int 等于原始Double,则Double 拥有一个整数值。

    如果你想避免显式转换,你可以改变

    .filter (x -> (int)(double)x == x)
    

    .filter (x -> x.intValue() == x)
    

    做同样的事情。

    【讨论】:

    • “铸造”Doubledouble?这对我来说听起来很可疑;当然,它会触发(自动)取消装箱,但正确的做法是转换未装箱的双精度值((int)x.doubleValue())。当我们已经讨论过这个问题时:比较 ``ìntwith a Double``` 是可行的,因为自动拆箱,但要做到真正正确,请执行以下操作:x.intValue() == x.doubleValue()
    • @tquadrat 将 Double 转换为 double 是必需的,因为您不能将 Double 直接转换为 int。是的,将 Double 转换为 double 等效于 x.doubleValue()。 “正确的方式”是见仁见智的问题。我认为x.intValue() == x 看起来更好,是的,由于自动拆箱,它可以工作。
    • – 是的,您需要将Double 转换为double,但这不是“强制转换”,而是“拆箱”……通常通过调用Double::doubleValue() 方法来完成,显式或隐式地,作为自动拆箱……
    【解决方案4】:

    试试这个:

    Collection<Integer> filterIntegers( final HashSet<Double> doubles )
    {
        final var retValue = doubles.stream()
            .filter( d -> d.doubleValue() == d.intValue() )
            .map( Double::intValue )
            .collect( Collector.toSet() );
        return retValue;
    }
    

    在我看来,将d 的真实(双)值与其整数值进行显式比较似乎是该要求的最精确实现。不进行四处转换,不涉及数学运算(尽管所有这些都会提供相同的结果!)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-28
      • 2014-03-04
      • 1970-01-01
      • 2011-08-27
      • 2020-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多