Comparing Variables

MJ variables are compared to other variables and Java primitives via methods similar to the mnenonic EQ, GE, GT, LE, LT, and NE comparison operators provided by MAPPER @IF. The IRelationalOperators interface defines these methods. For example:

public boolean EQ(final BigDecimal aDecimal, final MJVariable.CompareOption... anOption);
public boolean GE(final MJVariable aVariable, final MJVariable.CompareOption... anOption);
public boolean GT(final Integer anInt, final MJVariable.CompareOption... anOption);
public boolean LE(final String aString, final MJVariable.CompareOption... anOption);
public boolean LT(final MJVariable aVariable, final MJVariable.CompareOption... anOption);
public boolean NE(final Double aDouble, final MJVariable.CompareOption... anOption);

Note the extra CompareOption argument that specifies case sensitivity; if this argument is not provided, the default is to ignore case.

equals and compareTo

In addition, MJ variable classes support standard Java methods like equals and compareTo (compareToIgnoreCase is supported for MJString). Here are examples of MJ variable comparison using the standard methods and IRelationalOperators methods:

/////////////////////////////////////////////////////////////////////////
// @LDV <n1>i5=0, <n2>i5=0 .
// @LDV <firstOp>f1=1234.0, <secondOp>f10=12.34e+02 .
// @IF <firstOp> EQ <secondOp> LDV <n1>=10 . ; LDV <n2>=20 .

MJDecimal firstOp = new MJDecimal(VariableScope.LOCAL, 1, 0,
  EnumSet.noneOf(LoadOption.class), "1234.0");
MJDecimal secondOp = new MJDecimal(VariableScope.LOCAL, 10, 0,
  EnumSet.noneOf(LoadOption.class), "12.34e+02");
assert firstOp.EQ(secondOp, CompareOption.CASESENSITIVE);
assert firstOp.compareTo(secondOp) == 0;

/////////////////////////////////////////////////////////////////////////
// @LDV <decVar>f3.2=1.19, <n1>=0, <n2>=0 .
// @IF <decVar> LE 1.2 LDV <n1>=10 . ; LDV <n2>=20 .

BigDecimal decConstant= new BigDecimal("1.2");
MJDecimal decVar = new MJDecimal(VariableScope.LOCAL, 3, 2,
  EnumSet.noneOf(LoadOption.class), "1.19");
assert decVar.LE(decConstant);
assert decVar.compareTo(decConstant) <= 0;

/////////////////////////////////////////////////////////////////////////
// @LDV <intOp>i9='1234567.', <decOp>f13.2='12345670e-1', <n1>=0, <n2>=0 .
// @IF <intOp> EQ <decOp> LDV <n1>=10 . ; LDV <n2>=20 .

MJInteger intOp = new MJInteger(VariableScope.LOCAL, 9,
  EnumSet.noneOf(LoadOption.class), "1234567.");
MJDecimal decOp = new MJDecimal(VariableScope.LOCAL, 13, 2,
  EnumSet.noneOf(LoadOption.class), "12345670e-1");
assert intOp.EQ(decOp);
assert intOp.compareTo(decOp) == 0;

/////////////////////////////////////////////////////////////////////////
// @LDV <intVar>i10=00000000001, <n1>=0, <n2>=0 . .
// @IF '         1' EQ <secondOp> LDV <n1>=10 . ; LDV <n2>=20 .

MJInteger intVar = new MJInteger(VariableScope.LOCAL, 10,
  EnumSet.noneOf(LoadOption.class), "00000000001");
assert intVar.EQ("         1");
assert intVar.compareTo("         1") == 0;

/////////////////////////////////////////////////////////////////////////
// @LDV <strA>a16='abcdef7890ABCDEF', <strS>s20='Abcdef7890aBCDEF' .
// @LDV <strH>h18='ABCDEF7890abcdef', <n1>=0, <n2>=0 .
// @IF <strA> EQ <strS> & EQ <strH> LDV <n1>=10 . ; LDV <n2>=20 .

MJString strA = new MJString(VariableScope.LOCAL, MaprptVariableType.ALPHANUMERIC, 16,
  EnumSet.of(LoadOption.TRUNCATE), "abcdef7890ABCDEF");
MJString strS = new MJString(VariableScope.LOCAL, MaprptVariableType.STRING, 20,
  EnumSet.of(LoadOption.TRUNCATE), "Abcdef7890aBCDEF");
MJString strH = new MJString(VariableScope.LOCAL, MaprptVariableType.HOLLERITH, 18,
  EnumSet.of(LoadOption.TRUNCATE), "ABCDEF7890abcdef");

assert strA.EQ(strS);
assert strA.GT(strS, CompareOption.CASESENSITIVE);
assert strA.compareToIgnoreCase(strS) == 0;
assert strA.compareTo(strS) > 0;

assert strA.EQ(strH);
assert strA.NE(strH, CompareOption.CASESENSITIVE);
assert strA.compareToIgnoreCase(strH) == 0;
assert strA.compareTo(strH) != 0;

Type 'A' Variables and useAlphaCompare

The methods above handle type conversion and value "widening" similarly to MAPPER. The MJString class supports the special behavior of MAPPER's Alphanumeric (for example, <stkNum>A15) variables, subject to useAlphaCompare:

A scan of the variable contents stops when a space is encountered. Leading tabs (but not spaces) are discarded. When compared to a number, contents of "type A" variable are converted to a number (if possible) following the previous two constraints.

The isUsingAlphaCompare method determines if the special behavior of MAPPER type A variables applies (useAlphaCompare is true by default for MaprptVariableType.ALPHANUMERIC and false otherwise). The following examples illustrate MJString support for MAPPER type A behavior during comparison:

/////////////////////////////////////////////////////////////////////////
// @LDV f10.2=-56040.29 .
// @JUV,C  .
MJDecimal dec = new MJDecimal(VariableScope.LOCAL, 10, 2,
  EnumSet.noneOf(LoadOption.class), "-56040.29");
dec.formatter().commas();

// @LDV,C a16='-56,040.2900' .
MJString alpha = new MJString(VariableScope.LOCAL, MaprptVariableType.ALPHANUMERIC, 16,
  EnumSet.of(LoadOption.TRUNCATE), "-56,040.2900");
alpha.formatter().center();

// Decimal variable and A-type string variable are compared as numbers (raw, "Java" value
// of decimal variable and number parsed from string variable), i.e.,
// -56040.29 (dec) == -56040.2900 (alpha)
//
// @LDV i5=0, i5=0 .
// @IF  EQ  LDV =10 . ; LDV =20 .

assert alpha.isUsingAlphaCompare();
assert dec.EQ(alpha);
assert dec.compareTo(alpha) == 0;

/////////////////////////////////////////////////////////////////////////
// @LDV a6=' 01 b' .
MJString strA1 = new MJString(VariableScope.LOCAL, MaprptVariableType.ALPHANUMERIC, 6,
  EnumSet.of(LoadOption.TRUNCATE), " 01 b");

// @LDV a6='+1e0 c' .
MJString strA2 = new MJString(VariableScope.LOCAL, MaprptVariableType.ALPHANUMERIC, 6,
  EnumSet.of(LoadOption.TRUNCATE), "+1e0 c");

// Equality tests between A-type string variables containing content parseable as a number
// succeed, since MAPPER (and MJ) attempt to parse a number from A-type variables, and compared
// as numbers, the two A-type variables are same: " 01 b" -> 1 (strA1) == "+1e0 c" -> 1 (strA2)
//
// @LDV =0, =0 .
// @IF  EQ  LDV =10 . ; LDV =20 .

assert strA1.EQ(strA2);
assert strA1.EQ(strA2, CompareOption.CASESENSITIVE);
assert strA1.compareToIgnoreCase(strA2) == 0;
assert strA1.compareTo(strA2) == 0;

Variable Identity

In Java, besides object comparison, the equals method play a key role in determining the identity of an object. Whether an MJ variable uses the underlying value ("MJ identity") or the display value ("MAPPER identity") of the variable affects equals, compareTo and hashCode. See identity methods of MJ variables for details.