1*455610afSAndroid Build Coastguard Worker<?xml version="1.0"?> 2*455610afSAndroid Build Coastguard Worker<!-- 3*455610afSAndroid Build Coastguard WorkerLicensed to the Apache Software Foundation (ASF) under one or more 4*455610afSAndroid Build Coastguard Workercontributor license agreements. See the NOTICE file distributed with 5*455610afSAndroid Build Coastguard Workerthis work for additional information regarding copyright ownership. 6*455610afSAndroid Build Coastguard WorkerThe ASF licenses this file to You under the Apache License, Version 2.0 7*455610afSAndroid Build Coastguard Worker(the "License"); you may not use this file except in compliance with 8*455610afSAndroid Build Coastguard Workerthe License. You may obtain a copy of the License at 9*455610afSAndroid Build Coastguard Worker 10*455610afSAndroid Build Coastguard Worker http://www.apache.org/licenses/LICENSE-2.0 11*455610afSAndroid Build Coastguard Worker 12*455610afSAndroid Build Coastguard WorkerUnless required by applicable law or agreed to in writing, software 13*455610afSAndroid Build Coastguard Workerdistributed under the License is distributed on an "AS IS" BASIS, 14*455610afSAndroid Build Coastguard WorkerWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15*455610afSAndroid Build Coastguard WorkerSee the License for the specific language governing permissions and 16*455610afSAndroid Build Coastguard Workerlimitations under the License. 17*455610afSAndroid Build Coastguard Worker--> 18*455610afSAndroid Build Coastguard Worker<document> 19*455610afSAndroid Build Coastguard Worker <properties> 20*455610afSAndroid Build Coastguard Worker <title>What's new in Commons Lang 2.4?</title> 21*455610afSAndroid Build Coastguard Worker <author email="[email protected]">Commons Documentation Team</author> 22*455610afSAndroid Build Coastguard Worker </properties> 23*455610afSAndroid Build Coastguard Worker<body> 24*455610afSAndroid Build Coastguard Worker 25*455610afSAndroid Build Coastguard Worker<section name="What's new in Commons Lang 2.4?"> 26*455610afSAndroid Build Coastguard Worker<p>Commons Lang 2.4 is out, and the obvious question is: <em>"So what? What's changed?"</em>.</p> 27*455610afSAndroid Build Coastguard Worker<p>This article aims to briefly cover the changes and save you from having to dig through each JIRA 28*455610afSAndroid Build Coastguard Workerissue to see what went on in the year of development between Lang 2.3 and 2.4.</p> 29*455610afSAndroid Build Coastguard Worker<section name="Deprecations"> 30*455610afSAndroid Build Coastguard Worker<p>First, let us start with a couple of deprecations. As you can see in the release notes, we chose 31*455610afSAndroid Build Coastguard Workerto deprecate the <a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/ObjectUtils.html#appendIdentityToString(java.lang.StringBuffer,%20java.lang.Object)"><code>ObjectUtils.appendIdentityToString(StringBuffer, Object)</code></a> method as its 32*455610afSAndroid Build Coastguard Workernull handling did not match its design (see <a href="https://issues.apache.org/jira/browse/LANG-360">LANG-360</a> 33*455610afSAndroid Build Coastguard Workerfor more details. Instead users should use <code>ObjectUtils.identityToString(StringBuffer, Object)</code>.</p> 34*455610afSAndroid Build Coastguard Worker 35*455610afSAndroid Build Coastguard Worker<p>We also deprecated <a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/time/DateUtils.html#add(java.util.Date,%20int,%20int)"><code>DateUtils.add(java.util.Date, int, int)</code></a>. It should have been <code>private</code> 36*455610afSAndroid Build Coastguard Workerfrom the beginning; please let us know if you actually use it.</p> 37*455610afSAndroid Build Coastguard Worker</section> 38*455610afSAndroid Build Coastguard Worker<section name="The build"> 39*455610afSAndroid Build Coastguard Worker<p>Before we move on, a quick note on the build: we built 2.4 using Maven 2 and Java 1.4. We also tested that the Ant build passed the tests 40*455610afSAndroid Build Coastguard Workersuccessfully under Java 1.3, and that the classes compiled under Java 1.2. As it's been so long, we stopped building a Java 1.1-compatible jar. <strong>Most importantly</strong>, it <em>should</em> be a drop in replacement for Lang 2.3, but we recommend testing first, of course. Also, for those of you who work within an OSGi framework, the jar should be ready for OSGi. Now... time to move on. 41*455610afSAndroid Build Coastguard Worker</p> 42*455610afSAndroid Build Coastguard Worker</section> 43*455610afSAndroid Build Coastguard Worker<section name="New classes"> 44*455610afSAndroid Build Coastguard Worker<p>Three new classes were added, so let's cover those next.</p> 45*455610afSAndroid Build Coastguard Worker<p>Firstly, we added an <a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/math/IEEE754rUtils.html"><code>IEEE754rUtils</code></a> 46*455610afSAndroid Build Coastguard Workerclass to the <code>org.apache.commons.lang.math</code> package. 47*455610afSAndroid Build Coastguard WorkerThis candidate for ugly name of the month was needed to add <a href="https://en.wikipedia.org/wiki/IEEE_754r#min_and_max">IEEE-754r</a> 48*455610afSAndroid Build Coastguard Workersemantics for some of the <code>NumberUtils</code> methods. The relevant part of that 49*455610afSAndroid Build Coastguard WorkerIEEE specification in this case is the NaN handling for <code>min</code> and <code>max</code> methods, and 50*455610afSAndroid Build Coastguard Workeryou can read more about it in <a href="https://issues.apache.org/jira/browse/LANG-381">LANG-381</a>. 51*455610afSAndroid Build Coastguard Worker</p> 52*455610afSAndroid Build Coastguard Worker<p>Second and third on our newcomers list are the <a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/text/ExtendedMessageFormat.html"><code>ExtendedMessageFormat</code></a> class and its peer 53*455610afSAndroid Build Coastguard Worker<a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/text/FormatFactory.html"><code>FormatFactory</code></a> 54*455610afSAndroid Build Coastguard Workerinterface, both found in the <code>org.apache.commons.lang.text</code> package.</p> 55*455610afSAndroid Build Coastguard Worker<p>Together they allow you to take the <code>java.text.MessageFormat</code> class further and insert your own formatting elements.</p> 56*455610afSAndroid Build Coastguard Worker<p> 57*455610afSAndroid Build Coastguard WorkerBy way of an example, imagine that we have a need for custom formatting of an employee identification 58*455610afSAndroid Build Coastguard Workernumber or EIN. Perhaps, simplistically, our EIN is composed of a two-character department code 59*455610afSAndroid Build Coastguard Workerfollowed by a four-digit number, and that it is customary within our organization to render the EIN 60*455610afSAndroid Build Coastguard Workerwith a hyphen following the department identifier. Here we'll represent the EIN as a simple 61*455610afSAndroid Build Coastguard WorkerString (of course in real life we would likely create a class composed of department and number). 62*455610afSAndroid Build Coastguard WorkerWe can create a custom <code>Format</code> class: 63*455610afSAndroid Build Coastguard Worker<pre><code> 64*455610afSAndroid Build Coastguard Workerpublic class EINFormat extends Format { 65*455610afSAndroid Build Coastguard Worker private char[] idMask; 66*455610afSAndroid Build Coastguard Worker 67*455610afSAndroid Build Coastguard Worker public EINFormat() { 68*455610afSAndroid Build Coastguard Worker } 69*455610afSAndroid Build Coastguard Worker public EINFormat(char maskChar) { 70*455610afSAndroid Build Coastguard Worker idMask = new char[4]; 71*455610afSAndroid Build Coastguard Worker Arrays.fill(idMask, maskChar); 72*455610afSAndroid Build Coastguard Worker } 73*455610afSAndroid Build Coastguard Worker public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) { 74*455610afSAndroid Build Coastguard Worker String ein = (String) obj; //assume or assert length >= 2 75*455610afSAndroid Build Coastguard Worker if (idMask == null) { 76*455610afSAndroid Build Coastguard Worker return new StringBuffer(ein).insert(2, '-').toString(); 77*455610afSAndroid Build Coastguard Worker } 78*455610afSAndroid Build Coastguard Worker return new StringBuffer(ein.substring(0, 2)).append('-').append(idMask).toString(); 79*455610afSAndroid Build Coastguard Worker } 80*455610afSAndroid Build Coastguard Worker public Object parseObject(String source, ParsePosition pos) { 81*455610afSAndroid Build Coastguard Worker int idx = pos.getIndex(); 82*455610afSAndroid Build Coastguard Worker int endIdx = idx + 7; 83*455610afSAndroid Build Coastguard Worker if (source == null || source.length() < endIdx) { 84*455610afSAndroid Build Coastguard Worker pos.setErrorIndex(idx); 85*455610afSAndroid Build Coastguard Worker return null; 86*455610afSAndroid Build Coastguard Worker } 87*455610afSAndroid Build Coastguard Worker if (source.charAt(idx + 2) != '-') { 88*455610afSAndroid Build Coastguard Worker pos.setErrorIndex(idx); 89*455610afSAndroid Build Coastguard Worker return null; 90*455610afSAndroid Build Coastguard Worker } 91*455610afSAndroid Build Coastguard Worker pos.setIndex(endIdx); 92*455610afSAndroid Build Coastguard Worker return source.substring(idx, endIdx).deleteCharAt(2); 93*455610afSAndroid Build Coastguard Worker } 94*455610afSAndroid Build Coastguard Worker} 95*455610afSAndroid Build Coastguard Worker</code></pre> 96*455610afSAndroid Build Coastguard WorkerOur custom EIN format is made available for <code>MessageFormat</code>-style processing by a 97*455610afSAndroid Build Coastguard Worker<code>FormatFactory</code> implementation: 98*455610afSAndroid Build Coastguard Worker<pre><code> 99*455610afSAndroid Build Coastguard Workerpublic class EINFormatFactory implements FormatFactory { 100*455610afSAndroid Build Coastguard Worker public static final String EIN_FORMAT = "ein"; 101*455610afSAndroid Build Coastguard Worker public Format getFormat(String name, String arguments, Locale locale) { 102*455610afSAndroid Build Coastguard Worker if (EIN_FORMAT.equals(name)) { 103*455610afSAndroid Build Coastguard Worker if (arguments == null || "".equals(arguments)) { 104*455610afSAndroid Build Coastguard Worker return new EINFormat(); 105*455610afSAndroid Build Coastguard Worker } 106*455610afSAndroid Build Coastguard Worker return new EINFormat(arguments.charAt(0)); 107*455610afSAndroid Build Coastguard Worker } 108*455610afSAndroid Build Coastguard Worker return null; 109*455610afSAndroid Build Coastguard Worker } 110*455610afSAndroid Build Coastguard Worker} 111*455610afSAndroid Build Coastguard Worker</code></pre> 112*455610afSAndroid Build Coastguard Worker 113*455610afSAndroid Build Coastguard WorkerNow you simply provide a <code>java.util.Map<String, FormatFactory></code> registry (keyed 114*455610afSAndroid Build Coastguard Workerby format type) to <code>ExtendedMessageFormat</code>: 115*455610afSAndroid Build Coastguard Worker<pre><code> 116*455610afSAndroid Build Coastguard Workernew ExtendedMessageFormat("EIN: {0,ein}", Collections.singletonMap(EINFormatFactory.EIN_FORMAT, new EINFormatFactory())); 117*455610afSAndroid Build Coastguard Worker</code></pre> 118*455610afSAndroid Build Coastguard WorkerAs expected, this will render a String EIN "AA9999" as: <code>"EIN: AA-9999"</code>. 119*455610afSAndroid Build Coastguard Worker<br /> <br /> 120*455610afSAndroid Build Coastguard WorkerIf we wanted to trigger the EIN masking code, we could trigger that in the format pattern: 121*455610afSAndroid Build Coastguard Worker<pre><code> 122*455610afSAndroid Build Coastguard Workernew ExtendedMessageFormat("EIN: {0,ein,#}", Collections.singletonMap(EINFormatFactory.EIN_FORMAT, new EINFormatFactory())); 123*455610afSAndroid Build Coastguard Worker</code></pre> 124*455610afSAndroid Build Coastguard WorkerThis should render "AA9999" as: <code>"EIN: AA-####"</code>. 125*455610afSAndroid Build Coastguard Worker<br /> <br /> 126*455610afSAndroid Build Coastguard WorkerYou can also use <code>ExtendedMessageFormat</code> to override any or all of the built-in 127*455610afSAndroid Build Coastguard Workerformats supported by <code>java.text.MessageFormat</code>. Finally, note that because 128*455610afSAndroid Build Coastguard Worker<code>ExtendedMessageFormat</code> extends <code>MessageFormat</code> it should work in most 129*455610afSAndroid Build Coastguard Workercases as a <em>true</em> drop-in replacement. 130*455610afSAndroid Build Coastguard Worker</p> 131*455610afSAndroid Build Coastguard Worker</section> 132*455610afSAndroid Build Coastguard Worker<section name="New methods"> 133*455610afSAndroid Build Coastguard Worker<p>There were 58 new methods added to existing Commons Lang classes. Going through each one, one at a time would be dull, 134*455610afSAndroid Build Coastguard Workerand fortunately there are some nice groupings that we can discuss instead:</p> 135*455610afSAndroid Build Coastguard Worker<p>CharSet <a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/CharSet.html#getInstance(java.lang.String[])">getInstance(String[])</a> adds an additional builder method by which you can build a CharSet from multiple sets of characters at the same time. If you weren't aware of the CharSet class, it holds a set of characters created by a simple pattern language allowing constructs such as <code>"a-z"</code> and <code>"^a"</code> (everything but 'a'). It's most used by the CharSetUtils class, and came out of CharSetUtils.translate, a simple variant of the UNIX tr command.</p> 136*455610afSAndroid Build Coastguard Worker<p>ClassUtils <a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/ClassUtils.html">canonical name</a> methods are akin to the non '<code>Canonical</code>' methods, except they work with the more human readable <code>int[]</code> type names rather than the JVM versions of <code>[I</code>. This makes them useful for parsing input from developer's configuration files. </p> 137*455610afSAndroid Build Coastguard Worker<p>ClassUtils <a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/ClassUtils.html#toClass(java.lang.Object[])">toClass(String[])</a> is very easy to explain - it calls <code>toClass</code> on each <code>Object</code> in the array and returns an array of <code>Class</code> objects.</p> 138*455610afSAndroid Build Coastguard Worker<p>ClassUtils <a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/ClassUtils.html#wrappersToPrimitives(java.lang.Class[])">wrapper->primitive</a> conversions are the reflection of the pre-existing <code>primitiveToWrapper</code> methods. Again easy to explain, they turn an array of <code>Integer</code> into an array of <code>int[]</code>.</p> 139*455610afSAndroid Build Coastguard Worker<p>ObjectUtils <a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/ObjectUtils.html#identityToString(java.lang.StringBuffer,%20java.lang.Object)">identityToString(StringBuffer, Object)</a> is the StringBuffer variant of the pre-existing <code>identityToString</code> method. In case you've not met that before, it produces the toString that would have been produced by an Object if it hadn't been overridden.</p> 140*455610afSAndroid Build Coastguard Worker<p>StringEscapeUtils <a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/StringEscapeUtils.html#escapeCsv(java.lang.String)">CSV methods</a> are a new addition to our range of simple parser/printers. These, quite as expected, parse and unparse CSV text as per <a href="https://datatracker.ietf.org/doc/html/rfc4180">RFC-4180</a>.</p> 141*455610afSAndroid Build Coastguard Worker<p>StringUtils has a host of new methods, as always, and we'll leave these for later.</p> 142*455610afSAndroid Build Coastguard Worker<p>WordUtils <a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/WordUtils.html#abbreviate(java.lang.String,%20int,%20int,%20java.lang.String)">abbreviate</a> finds the first space after the lower limit and abbreviates the text.</p> 143*455610afSAndroid Build Coastguard Worker<p>math.<a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/math/IntRange.html#toArray()">IntRange</a>/<a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/math/LongRange.html#toArray()">LongRange.toArray</a> turn the range into an array of primitive <code>int</code>/<code>long</code>s contained in the range.</p> 144*455610afSAndroid Build Coastguard Worker<p>text.StrMatch.<a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/text/StrMatcher.html#isMatch(char[],%20int)">isMatch(char[], int)</a> is a helper method for checking whether there was a match with the StrMatcher objects.</p> 145*455610afSAndroid Build Coastguard Worker<p>time.DateFormatUtils <a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/time/DateFormatUtils.html">format(Calendar, ...)</a> provide Calendar variants for the pre-existing format methods. If these are new to you, they are helper methods to formatting a date.</p> 146*455610afSAndroid Build Coastguard Worker<p>time.DateUtils <a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/time/DateUtils.html">getFragment*</a> methods are used to splice the time element out of Date. If you have <code>2008/12/13 14:57</code>, then these could, for example, pull out the 13.</p> 147*455610afSAndroid Build Coastguard Worker<p>time.DateUtils <a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/time/DateUtils.html">setXxx methods</a> round off our walk through the methods - the setXxx variant of the existing addXxx helper methods.</p> 148*455610afSAndroid Build Coastguard Worker</section> 149*455610afSAndroid Build Coastguard Worker 150*455610afSAndroid Build Coastguard Worker<section name="StringUtils methods"> 151*455610afSAndroid Build Coastguard Worker<p>The <code>StringUtils</code> class is a little large, isn't it? Sorry, but it's gotten bigger. 152*455610afSAndroid Build Coastguard Worker</p> 153*455610afSAndroid Build Coastguard Worker<ul> 154*455610afSAndroid Build Coastguard Worker <li><a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/StringUtils.html#containsOnly(java.lang.String,%20char[])">boolean containsAny(String, char[])</a></li> 155*455610afSAndroid Build Coastguard Worker <li><a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/StringUtils.html#containsOnly(java.lang.String,%20java.lang.String)">boolean containsAny(String, String)</a></li> 156*455610afSAndroid Build Coastguard Worker <li><a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/StringUtils.html#endsWith(java.lang.String,%20java.lang.String)">boolean endsWith(String, String)</a></li> 157*455610afSAndroid Build Coastguard Worker <li><a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/StringUtils.html#endsWithIgnoreCase(java.lang.String,%20java.lang.String)">boolean endsWithIgnoreCase(String, String)</a></li> 158*455610afSAndroid Build Coastguard Worker <li><a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/StringUtils.html#getCommonPrefix(java.lang.String[])">String getCommonPrefix(String[])</a></li> 159*455610afSAndroid Build Coastguard Worker <li><a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/StringUtils.html#indexOfDifference(java.lang.String[])">int indexOfDifference(String[])</a></li> 160*455610afSAndroid Build Coastguard Worker <li><a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/StringUtils.html#length(java.lang.String)">int length(String)</a></li> 161*455610afSAndroid Build Coastguard Worker <li><a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/StringUtils.html#removeEndIgnoreCase(java.lang.String,%20java.lang.String)">String removeEndIgnoreCase(String, String)</a></li> 162*455610afSAndroid Build Coastguard Worker <li><a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/StringUtils.html#removeStartIgnoreCase(java.lang.String,%20java.lang.String)">String removeStartIgnoreCase(String, String)</a></li> 163*455610afSAndroid Build Coastguard Worker <li><a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/StringUtils.html#replaceEach(java.lang.String,%20java.lang.String[],%20java.lang.String[])">String replaceEach(String, String[], String[])</a></li> 164*455610afSAndroid Build Coastguard Worker <li><a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/StringUtils.html#replaceEachRepeatedly(java.lang.String,%20java.lang.String[],%20java.lang.String[])">String replaceEachRepeatedly(String, String[], String[])</a></li> 165*455610afSAndroid Build Coastguard Worker <li><a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/StringUtils.html#splitByCharacterType(java.lang.String)">String[] splitByCharacterType(String)</a></li> 166*455610afSAndroid Build Coastguard Worker <li><a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/StringUtils.html#splitByCharacterTypeCamelCase(java.lang.String)">String[] splitByCharacterTypeCamelCase(String)</a></li> 167*455610afSAndroid Build Coastguard Worker <li><a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/StringUtils.html#splitByWholeSeparatorPreserveAllTokens(java.lang.String,%20java.lang.String)">String[] splitByWholeSeparatorPreserveAllTokens(String, String)</a></li> 168*455610afSAndroid Build Coastguard Worker <li><a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/StringUtils.html#splitByWholeSeparatorPreserveAllTokens(java.lang.String,%20java.lang.String,%20int)">String[] splitByWholeSeparatorPreserveAllTokens(String, String, int)</a></li> 169*455610afSAndroid Build Coastguard Worker <li><a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/StringUtils.html#startsWith(java.lang.String,%20java.lang.String)">boolean startsWith(String, String)</a></li> 170*455610afSAndroid Build Coastguard Worker <li><a href="https://commons.apache.org/proper/commons-lang/javadocs/api-2.4/org/apache/commons/lang/StringUtils.html#startsWithIgnoreCase(java.lang.String,%20java.lang.String)">boolean startsWithIgnoreCase(String, String)</a></li> 171*455610afSAndroid Build Coastguard Worker</ul> 172*455610afSAndroid Build Coastguard Worker 173*455610afSAndroid Build Coastguard Worker<p>Hopefully they are in many cases self-describing. Rather than spend a lot of time describing them, we'll let you read the Javadoc of the ones that interest you.</p> 174*455610afSAndroid Build Coastguard Worker 175*455610afSAndroid Build Coastguard Worker</section> 176*455610afSAndroid Build Coastguard Worker 177*455610afSAndroid Build Coastguard Worker<section name="What's fixed in Lang 2.4?"> 178*455610afSAndroid Build Coastguard Worker<p>In addition to new things, there are the bugfixes. As you can tell from the release notes, there are a good few - 24 in fact according to JIRA. Here are some of the interesting ones: </p> 179*455610afSAndroid Build Coastguard Worker<ul> 180*455610afSAndroid Build Coastguard Worker<li><a href="https://issues.apache.org/jira/browse/LANG-393">LANG-393</a> - We fixed EqualsBuilder so that it understands that BigDecimals are equal even when they think they're not. It seems very likely that usually you will want "29.0" and "29.00" to be equal, even if BigDecimal disagrees. </li> 181*455610afSAndroid Build Coastguard Worker<li><a href="https://issues.apache.org/jira/browse/LANG-380">LANG-380</a> - Chances are you'll know if you met this one. Fraction.reduce has an infinite loop if the numerator is 0. </li> 182*455610afSAndroid Build Coastguard Worker<li><a href="https://issues.apache.org/jira/browse/LANG-369">LANG-369</a>, <a href="https://issues.apache.org/jira/browse/LANG-367">LANG-367</a>, <a href="https://issues.apache.org/jira/browse/LANG-334">LANG-334</a> - Threading bugs - we improved how things work in concurrency situations for ExceptionUtils, FastDateFormat and Enum. </li> 183*455610afSAndroid Build Coastguard Worker<li><a href="https://issues.apache.org/jira/browse/LANG-346">LANG-346</a> - DateUtils.round was getting things wrong for minutes and seconds. </li> 184*455610afSAndroid Build Coastguard Worker<li><a href="https://issues.apache.org/jira/browse/LANG-328">LANG-328</a> - LocaleUtils.toLocale was broken if there was no country code defined. </li> 185*455610afSAndroid Build Coastguard Worker</ul> 186*455610afSAndroid Build Coastguard Worker</section> 187*455610afSAndroid Build Coastguard Worker 188*455610afSAndroid Build Coastguard Worker<section name="So long, farewell..."> 189*455610afSAndroid Build Coastguard Worker<p>Hopefully that was all of interest. Don't forget to download <a href="https://commons.apache.org/lang/download_lang.cgi">Lang 2.4</a>, or, for the Maven repository users, upgrade your <version> tag to 2.4. Please feel free to raise any questions you might have on the <a href="mail-lists.html">mailing lists</a>, and report bugs or enhancements in the <a href="issue-tracking.html">issue tracker</a>.</p> 190*455610afSAndroid Build Coastguard Worker</section> 191*455610afSAndroid Build Coastguard Worker 192*455610afSAndroid Build Coastguard Worker</section> 193*455610afSAndroid Build Coastguard Worker 194*455610afSAndroid Build Coastguard Worker</body> 195*455610afSAndroid Build Coastguard Worker</document> 196