Core Java coding question - converting String to BigDecimal
There are times while coding you need to convert an entity of one data type to another or validate a given input.
Q. Can you write a generic function that converts an amount in String to double amount?
A.
Step 1: Ask the right questions and arrive at a more detailed requirements.
- Handling negative amounts like -34.01 or (34.01) with a parenthesis. Parentheses denote a negative value.
- Handling commas in formatted values like 1,205.45, etc.
- Handling negative scenarios like amount being empty as in ( ).
Step 2: Let's use a TDD (Test Driven Development approach).
So, write a skeleton class so that all our unit tests fail.
package com.mycompany.app5; import java.math.BigDecimal; import java.text.ParseException; public class ConvertingAmount { public BigDecimal convert(String amount) throws ParseException { BigDecimal result = null; return result; } }
Next, write the unit tests based on the above requirements so that all fail, but cover the requirements.
package com.mycompany.app5; import java.math.BigDecimal; import java.text.ParseException; import junit.framework.Assert; import org.junit.Before; import org.junit.Test; public class ConvertingAmountTest { private ConvertingAmount ca; @Before public void setUp() { ca = new ConvertingAmount(); } @Test public void testPositiveAmount() throws ParseException { BigDecimal converted = ca.convert("2255.001"); Assert.assertEquals(new BigDecimal("2255.001"), converted); } @Test public void testNegativeAmount() throws ParseException { BigDecimal converted = ca.convert("-2255.001"); Assert.assertEquals(new BigDecimal("-2255.001"), converted); } @Test public void testNegativeAmountWithParanthes() throws ParseException { BigDecimal converted = ca.convert("(2255.001)"); Assert.assertEquals(new BigDecimal("-2255.001"), converted); } @Test public void testPosiotiveAmountFormatted() throws ParseException { BigDecimal converted = ca.convert("2,255.001"); Assert.assertEquals(new BigDecimal("2255.001"), converted); } @Test public void testNegativeAmountFormatted() throws ParseException { BigDecimal converted = ca.convert("-2,255.001"); Assert.assertEquals(new BigDecimal("-2255.001"), converted); } @Test public void testNegativeAmountWithParenthesesFormatted() throws ParseException { BigDecimal converted = ca.convert("(2,255.001)"); Assert.assertEquals(new BigDecimal("-2255.001"), converted); } @Test(expected = ParseException.class) public void testExceptionalScenario() throws ParseException { String amount = "()"; ca.convert(amount); } @Test(expected = ParseException.class) public void testExceptionalScenario2() throws ParseException { String amount = "abc"; ca.convert(amount); } }
Step 3: Implement the functionality, so that all the above unit tests pass.
package com.mycompany.app5; import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.ParseException; import org.apache.commons.lang.StringUtils; public class ConvertingAmount { public BigDecimal convert(String amount) throws ParseException { BigDecimal result = null; DecimalFormat df = new DecimalFormat("#,#00.00;-#,#00.00"); //positive;negative //convert (2255.001) to -2255.001 and (2,255.001) to -2255.001 if (StringUtils.isNotBlank(amount) && amount.startsWith("(") && amount.endsWith(")")) { String valueStr = amount.substring(1, amount.length() - 1); Number valInParenthesis = df.parse(valueStr.trim()); result = BigDecimal.valueOf(valInParenthesis.doubleValue()).negate(); amount = result.toPlainString(); } //parse 2,255.001 and -2,255.001 Number val = df.parse(amount); result = BigDecimal.valueOf(val.doubleValue()); return result; } }
Now, all green.
0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home