主要用于记录日常工作中,简单又容易犯错的问题,以便随着时间遗忘,相同问题重复踩坑。
一、BigDecimal初始化
BigDecimal是java中用到比较多的高精度数据类型,搞清楚不同方式初始化BigDecimal对象,以避免我们经常犯一些低级的错误。。
new BigDecimal()
字符串初始化,其入参一般是字符串,例如:new BigDecimal(“0.01”)
其对应源码如下:
/**
* Translates an {@code int} into a {@code BigDecimal}. The
* scale of the {@code BigDecimal} is zero.
*
* @param val {@code int} value to be converted to
* {@code BigDecimal}.
* @since 1.5
*/
public BigDecimal(int val) {
this.intCompact = val;
this.scale = 0;
this.intVal = null;
}
/**
* Translates a {@code double} into a {@code BigDecimal} which
* is the exact decimal representation of the {@code double}'s
* binary floating-point value. The scale of the returned
* {@code BigDecimal} is the smallest value such that
* <tt>(10<sup>scale</sup> × val)</tt> is an integer.
* <p>
* <b>Notes:</b>
* <ol>
* <li>
* The results of this constructor can be somewhat unpredictable.
* One might assume that writing {@code new BigDecimal(0.1)} in
* Java creates a {@code BigDecimal} which is exactly equal to
* 0.1 (an unscaled value of 1, with a scale of 1), but it is
* actually equal to
* 0.1000000000000000055511151231257827021181583404541015625.
* This is because 0.1 cannot be represented exactly as a
* {@code double} (or, for that matter, as a binary fraction of
* any finite length). Thus, the value that is being passed
* <i>in</i> to the constructor is not exactly equal to 0.1,
* appearances notwithstanding.
*
* <li>
* The {@code String} constructor, on the other hand, is
* perfectly predictable: writing {@code new BigDecimal("0.1")}
* creates a {@code BigDecimal} which is <i>exactly</i> equal to
* 0.1, as one would expect. Therefore, it is generally
* recommended that the {@linkplain #BigDecimal(String)
* <tt>String</tt> constructor} be used in preference to this one.
*
* <li>
* When a {@code double} must be used as a source for a
* {@code BigDecimal}, note that this constructor provides an
* exact conversion; it does not give the same result as
* converting the {@code double} to a {@code String} using the
* {@link Double#toString(double)} method and then using the
* {@link #BigDecimal(String)} constructor. To get that result,
* use the {@code static} {@link #valueOf(double)} method.
* </ol>
*
* @param val {@code double} value to be converted to
* {@code BigDecimal}.
* @throws NumberFormatException if {@code val} is infinite or NaN.
*/
public BigDecimal(double val) {
this(val,MathContext.UNLIMITED);
}
/**
* Translates the string representation of a {@code BigDecimal}
* into a {@code BigDecimal}. The string representation consists
* of an optional sign, {@code '+'} (<tt> '\u002B'</tt>) or
* {@code '-'} (<tt>'\u002D'</tt>), followed by a sequence of
* zero or more decimal digits ("the integer"), optionally
* followed by a fraction, optionally followed by an exponent.
*
* <p>The fraction consists of a decimal point followed by zero
* or more decimal digits. The string must contain at least one
* digit in either the integer or the fraction. The number formed
* by the sign, the integer and the fraction is referred to as the
* <i>significand</i>.
*
* <p>The exponent consists of the character {@code 'e'}
* (<tt>'\u0065'</tt>) or {@code 'E'} (<tt>'\u0045'</tt>)
* followed by one or more decimal digits. The value of the
* exponent must lie between -{@link Integer#MAX_VALUE} ({@link
* Integer#MIN_VALUE}+1) and {@link Integer#MAX_VALUE}, inclusive.
*
* <p>More formally, the strings this constructor accepts are
* described by the following grammar:
* <blockquote>
* <dl>
* <dt><i>BigDecimalString:</i>
* <dd><i>Sign<sub>opt</sub> Significand Exponent<sub>opt</sub></i>
* <dt><i>Sign:</i>
* <dd>{@code +}
* <dd>{@code -}
* <dt><i>Significand:</i>
* <dd><i>IntegerPart</i> {@code .} <i>FractionPart<sub>opt</sub></i>
* <dd>{@code .} <i>FractionPart</i>
* <dd><i>IntegerPart</i>
* <dt><i>IntegerPart:</i>
* <dd><i>Digits</i>
* <dt><i>FractionPart:</i>
* <dd><i>Digits</i>
* <dt><i>Exponent:</i>
* <dd><i>ExponentIndicator SignedInteger</i>
* <dt><i>ExponentIndicator:</i>
* <dd>{@code e}
* <dd>{@code E}
* <dt><i>SignedInteger:</i>
* <dd><i>Sign<sub>opt</sub> Digits</i>
* <dt><i>Digits:</i>
* <dd><i>Digit</i>
* <dd><i>Digits Digit</i>
* <dt><i>Digit:</i>
* <dd>any character for which {@link Character#isDigit}
* returns {@code true}, including 0, 1, 2 ...
* </dl>
* </blockquote>
*
* <p>The scale of the returned {@code BigDecimal} will be the
* number of digits in the fraction, or zero if the string
* contains no decimal point, subject to adjustment for any
* exponent; if the string contains an exponent, the exponent is
* subtracted from the scale. The value of the resulting scale
* must lie between {@code Integer.MIN_VALUE} and
* {@code Integer.MAX_VALUE}, inclusive.
*
* <p>The character-to-digit mapping is provided by {@link
* java.lang.Character#digit} set to convert to radix 10. The
* String may not contain any extraneous characters (whitespace,
* for example).
*
* <p><b>Examples:</b><br>
* The value of the returned {@code BigDecimal} is equal to
* <i>significand</i> × 10<sup> <i>exponent</i></sup>.
* For each string on the left, the resulting representation
* [{@code BigInteger}, {@code scale}] is shown on the right.
* <pre>
* "0" [0,0]
* "0.00" [0,2]
* "123" [123,0]
* "-123" [-123,0]
* "1.23E3" [123,-1]
* "1.23E+3" [123,-1]
* "12.3E+7" [123,-6]
* "12.0" [120,1]
* "12.3" [123,1]
* "0.00123" [123,5]
* "-1.23E-12" [-123,14]
* "1234.5E-4" [12345,5]
* "0E+7" [0,-7]
* "-0" [0,0]
* </pre>
*
* <p>Note: For values other than {@code float} and
* {@code double} NaN and ±Infinity, this constructor is
* compatible with the values returned by {@link Float#toString}
* and {@link Double#toString}. This is generally the preferred
* way to convert a {@code float} or {@code double} into a
* BigDecimal, as it doesn't suffer from the unpredictability of
* the {@link #BigDecimal(double)} constructor.
*
* @param val String representation of {@code BigDecimal}.
*
* @throws NumberFormatException if {@code val} is not a valid
* representation of a {@code BigDecimal}.
*/
public BigDecimal(String val) {
this(val.toCharArray(), 0, val.length());
}
BigDecimal.valueOf()
valueOf初始化,其入参是double类型,例如:BigDecimal.valueOf(0.01)
其对应源码如下:
/**
* Translates a {@code long} value into a {@code BigDecimal}
* with a scale of zero. This {@literal "static factory method"}
* is provided in preference to a ({@code long}) constructor
* because it allows for reuse of frequently used
* {@code BigDecimal} values.
*
* @param val value of the {@code BigDecimal}.
* @return a {@code BigDecimal} whose value is {@code val}.
*/
public static BigDecimal valueOf(long val) {
if (val >= 0 && val < zeroThroughTen.length)
return zeroThroughTen[(int)val];
else if (val != INFLATED)
return new BigDecimal(null, val, 0, 0);
return new BigDecimal(INFLATED_BIGINT, val, 0, 0);
}
/**
* Translates a {@code double} into a {@code BigDecimal}, using
* the {@code double}'s canonical string representation provided
* by the {@link Double#toString(double)} method.
*
* <p><b>Note:</b> This is generally the preferred way to convert
* a {@code double} (or {@code float}) into a
* {@code BigDecimal}, as the value returned is equal to that
* resulting from constructing a {@code BigDecimal} from the
* result of using {@link Double#toString(double)}.
*
* @param val {@code double} to convert to a {@code BigDecimal}.
* @return a {@code BigDecimal} whose value is equal to or approximately
* equal to the value of {@code val}.
* @throws NumberFormatException if {@code val} is infinite or NaN.
* @since 1.5
*/
public static BigDecimal valueOf(double val) {
// Reminder: a zero double returns '0.0', so we cannot fastpath
// to use the constant ZERO. This might be important enough to
// justify a factory approach, a cache, or a few private
// constants, later.
return new BigDecimal(Double.toString(val));
}
其实两种方式都可以使用,一般情况下没什么区别,但涉及到有小数位的数值时,new BigDecimal(double)类型时,小数的精度出现扩展,
BigDecimal bd1 = new BigDecimal(0.01);
BigDecimal bd2 = BigDecimal.valueOf(0.01);
System.out.println("bd1 = " + bd1);
System.out.println("bd2 = " + bd2);
控制台输出如下:
bd1 = 0.01000000000000000020816681711721685132943093776702880859375
bd2 = 0.01
BigDecimal.valueOf(0.01),那么0.01会先被转化为字符串类型的对象,然后再调用 new BigDecimal() 方法,这样可以保证精度不会丢失,所以 BigDecimal.valueOf(0.01) 可以理解成等价于 new BigDecimal(“0.01”) 。
二、二维码解析之PURE_BARCODE模式
采用Google的zxing技术进行解析二维码时,如果遇到复杂的二维码时,经常会发现zxing抛出com.google.zxing.NotFoundException异常
其实识别图片时,由于图层负责,无法正常解析到正确的图片信息,这个时候解析时,就需要开启PURE_BARCODE模式
Map <DecodeHintType, Object> hintsMap = new EnumMap <DecodeHintType, Object> (DecodeHintType.class);
// 设置它的 hints二维码格式是纯二维码
hintsMap.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
MultiFormatReader formatReader = new MultiFormatReader();
List<BufferedImage> imageList = extractImage();
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(imageList.get(0))));
String qcText = formatReader..decode(binaryBitmap, hintsMap).getText();