java重载运算符_流形:Java的运算符重载

java重载运算符

Manifold扩展依赖项插入Java中,以提供无缝的运算符重载功能。 通过实现一个或多个预定义的运算符方法,可以为任何类类型安全地提供算术,关系和单位运算 。 您可以直接在您的类中实现运算符方法,也可以使用扩展方法为您原本无法控制的类实现运算符。 例如,使用扩展方法ManifoldBigDecimal提供了运算符实现,因此您可以编写如下代码:

BigDecimal result = bigValue1 + bigValue2;

使用单位表达式,可以更轻松地使用BigDecimal和其他类型:

BigDecimal result = 3.14bd * 10.75bd; // `bd` makes BigDecimals

通过单元和操作员过载进行精确测量:

Length distance = 65 mph * 3.2 hr;
HeatCapacity kBoltzmann = 1.380649e-23r J/dK;

算术和否定运算符

任何类型都可以通过实现以下一种或多种运算符方法来支持算术运算符:

算术

操作方式 方法
a + b a.plus(b)
a - b a.minus(b)
a * b a.times(b)
a / b a.div(b)
a % b a.rem(b)

否定

操作方式 方法
-a a.unaryMinsu()

注意运算符方法不属于您实现的类或接口。 相反,您可以通过定义具有相同签名的方法来简单地在结构上实现它们。 请注意,您可以实现同一方法的多个不同版本,具体取决于参数类型。

这是一个简单的示例,演示如何实现+运算符:

public class Point {
  public final int x, y;
  public Point(int x, int y) {this.x = x; this.y = y;}
  
  public Point plus(Point that) {
    return new Point(x + that.x, y + that.y);
  }
}

var a = new Point(1, 2);
var b = new Point(3, 4);

var sum = a + b; // Point(4, 6)

由于运算符方法是结构性的,因此可以定义多个 plus()方法:

public Point plus(int[] coord) {
  if(coord.length != 2) {
    throw new IllegalArgumentException();
  }
  return new Point(x + coord[0], y + coord[1]);
}

关系运算符

您可以使用ComparableUsing和/或Comparable接口的组合来实现关系运算符。

manifold.ext.api.ComparableUsing

关系运算符可以与ComparableUsing接口一起全部实现,该接口扩展了Comparable以提供特定于运算符的API。

boolean compareToUsing( T that, Operator op );

其中Operator是一个enum ,它为关系运算符指定常数。

操作方式 可比的使用Impl 可比的Impl
a > b a.compareToUsing(b, GT) a.compareTo(b) > 0
a >= b a.compareToUsing(b, GE) a.compareTo(b) >= 0
a < b a.compareToUsing(b, LT) a.compareTo(b) < 0
a <= b a.compareToUsing(b, LE) a.compareTo(b) <= 0

ComparableUsing提供了compareToUsing()的默认实现,该默认实现委托给关系运算符的>>=<<=子集的ComparablecompareTo()实现。 对于==!=子集, ComparableUsing委托给该类型的equals()方法(稍后将详细介绍平等性)。 此行为适用于大多数类型,因此通常您只需要向您的类型的implementsextends子句中添加ComparableUsing即可ComparableUsing仅实现Comparable 。 因此,在Point示例中增加了关系运算符支持:

public class Point implements ComparableUsing {
  public final int x, y;
  public Point(int x, int y) {this.x = x; this.y = y;}
  
  public Point plus(Point that) {
    return new Point(x + that.x, y + that.y);
  }
  
  public int compareTo(Point that) {
    return x - that.x;
  }
}

现在,您可以像这样轻松地比较“点”值:

if (pt1 >= pt2) ...

java.lang.Comparable

如果您对支持==!=不感兴趣,并且您的类型实现了Comparable接口,它将自动支持关系运算符的>>=<<=子集。 例如,既java.lang.Stringjava.time.LocalDate实现compareTo()从方法Comparable ,这意味着它们可以在关系表达式中使用的:

String name1;
String name2;
...
if (name1 > name2) {...}
LocalDate date1;
LocalDate date2;
...
if (date1 > date2) {...}
还请参见:

平等经营者

要实现关系运算符的==!=子集,必须实现ComparableUsing接口。 默认情况下, ComparableUsing委托给您类型的equals()方法,但是您可以通过重写CopmarableUsing实现中的CopmarableUsing equalityMode()方法来轻松覆盖此行为。 EqualityMode枚举提供了可用的模式:

/**
 * The mode indicating the method used to implement {@code ==} and {@code !=} operators.
 */
enum EqualityMode
{
  /** Use the {@code #compareTo()} method to implement `==` and `!=` */
  CompareTo,

  /** Use the {@code equals()} method to implement `==` and `!=` (default) */
  Equals,

  /** Use {@code identity} comparison for `==` and `!=`, note this is the same as Java's normal {@code ==} behavior } */
  Identity
}

根据您的CompareToUsing#equalityMode()实现返回的EqualityMode==!=运算符使用以下方法进行编译:

操作方式 Equals <small>(默认)</ small> CompareTo Identity
a == b a.equals(b) a.compareToUsing(b, EQ) a == b
a != b !a.equals(b) a.compareToUsing(b, NE) a != b

注意:歧管为==!=生成有效的, 空安全的代码。 例如,使用Equals模式的a == b编译为:

a == b || a != null && b != null && a.equals(b)

If you need something more customized you can override compareToUsing() with your own logic for any of the operators, including == and != . To enable == on Point more effectively, you can accept the default behavior of ComparableUsing and implement equals() :
public boolean equals(Object that) {
  return this == that || that != null && getClass() == that.getClass() && 
         x == ((Point)that).x && y == ((Point)that).y;
}

请注意,如果实现equals() ,请始终考虑实现hashCode() ,否则在与Map和其他数据结构一起使用时,您的类型可能无法正常工作:

public int hashCode() {
  return Objects.hash(x, y); 
}

有时最好使用CompareTo模式。 例如, RationalBigDecimalBigInteger==!=实现使用CompareTo模式,因为在那些类中, compareTo()反映了它们所建模数字的面值的相等性,例如1.0 == 1.00,即在许多用例中的期望行为。 在那种情况下,只需重写equalityMode()以返回CompareTo

@Override
public EqualityMode equalityMode() {
  return CompareTo;
}
还请参见:

单位经营者

单位或“绑定”操作对于歧管框架是唯一的。 它们提供了功能强大且简洁的语法,可以应用于广泛的应用程序。 您可以使用prefixBind()postfixBind()方法实现运算符:

操作方式 后缀绑定 前缀绑定
ab b.postfixBind(a) a.prefixBind(b)

如果类型a工具R prefixBind(B)其中B距离的类型分配的b ,则ab编译作为方法调用a.prefixBind(b)具有式R 否则,如果类型b器具R postfixBind(A)其中A是从分配的类型a ,然后ab编译作为方法调用b.postfixBind(a)具有式R

此功能启用以下表达式:

Mass m = 5 kg;
Force f = 5 kg * 9.8 m/s/s;
for (int i: 1 to 10) {...}

阅读更多有关单位表达式的信息

扩展方法运算符

使用扩展方法,您可以为原本无法控制的类提供操作员实现。 例如,Manifold为BigDecimalBigInteger提供了运算符扩展。 这些扩展是在manifold-science依赖中实现的。

这是BigDecimal+扩展名:

@Extension
public abstract class ManBigDecimalExt implements ComparableUsing {
  /** Supports binary operator {@code +} */
  public static BigDecimal plus(@This BigDecimal thiz, BigDecimal that) {
    return thiz.add(that);
  }
  ...
}
```
Now you can perform arithmetic and comparisons using operator expressions:
```java
if (bd1 >= bd2) {
  BigDecimal result = bd1 + bd2;
  . . .
}

请注意, manifold-sciencemanifold-collections模块广泛使用运算符重载和单位表达式。

翻译自: https://jaxenter.com/manifold-operator-overloading-java-163232.html

java重载运算符

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java不直接支持运算符重载运算符重载是指为类定义自定义的运算符行为。然而,通过使用Manifold扩展依赖项,可以在Java中实现类似的功能。Manifold扩展依赖项允许您通过实现预定义的运算符方法来为类提供算术、关系和单位运算符的功能。您可以直接在您的类中实现这些运算符方法,也可以使用扩展方法为您原本无法控制的类实现运算符。例如,您可以使用Manifold扩展方法为BigDecimal提供运算符实现,从而可以像这样编写代码:BigDecimal result = bigValue1 + bigValue2。\[1\] Java不直接支持运算符重载的原因有几个方面。首先,运算符重载会使JVM变得复杂,并且可能导致性能下降。C++是一种支持运算符重载的语言,但是C++的性能在任何时代都可以秒杀Java。其次,Java的设计目标之一是便于静态分析和工具化。运算符重载是一种动态特性,而动态语言的形式化静态分析方法已经有成熟的方法论。最后,Java是一种面向对象的语言,而不是像Ruby那样彻底面向对象的语言。虽然Ruby对运算符重载的支持非常优秀,但Java更注重在对象之间进行消息传递和方法调用。\[2\] 虽然Java不直接支持运算符重载,但您可以通过定义方法来实现类似的功能。例如,您可以定义一个plus()方法来执行加法操作。这样,您可以像这样使用plus()方法:Point result = point1.plus(point2)。您还可以定义多个plus()方法,以便接受不同类型的参数。例如,您可以定义一个plus()方法,接受一个int数组作为参数,并返回一个新的Point对象。\[3\] #### 引用[.reference_title] - *1* *3* [java重载运算符_流形Java运算符重载](https://blog.csdn.net/diluan6799/article/details/106827567)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [java重载_为什么Java不支持运算符重载?](https://blog.csdn.net/weixin_39632728/article/details/110741608)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值