feilong-core 亮点
- 有常用专属工具类 (如处理日期的
DateUtil
,处理集合的CollectionsUtil
,类型转换的ConvertUtil
等等等) - 有常用JAVA常量类 (如日期格式
DatePattern
, 时间间隔TimeInterval
等等等) - 不必要的
Exception
转成RuntimeException
,减少不必要的代码 - 国内
中文注释
最完善的API - 有完善的单元测试
1."看一眼就会爱上他"的方法
1.1 ConvertUtil.toList(T…)
曾经,你调用某个api时,该api需要一个list参数, 但是你现在只有单对象
你需要这么写
List<Long> itemIds = new ArrayList<>();
itemIds.add(itemId);
sdkItemManager.findItemImageByItemIds(itemIds);
总感觉怪怪的, 很烦人
你现在可以这么写
sdkItemManager.findItemImageByItemIds(ConvertUtil.toList(itemId));
一行代码,轻松快乐的写代码
同样,下面的代码
List<Long> skuIds = new ArrayList<>();
skuIds.add(9L);
skuIds.add(10L);
skuIds.add(13L);
skuIds.add(18L);
skuIds.add(20L);
BundleValidateResult result = bundleManager.validateBundle(skuIds);
依然,可以简写
List<Long> skuIds=ConvertUtil.toList(9L, 10L, 13L, 18L, 20L);
BundleValidateResult result = bundleManager.validateBundle(skuIds);
代码的可读性更高,更简洁
PS:如果使用 import static 代码可以更简洁
1.2 CollectionsUtil.getPropertyValueList(Collection<O>, String)
循环集合
objectCollection
,取到对象指定的属性propertyName
的值,拼成List
(ArrayList).
很多场合下,手头上有 bean list
, 但是操作的时候,你可能需要使用每个bean里面的某个属性
比如: 提取SalesOrderCommand list里面的id属性组成 List<Long>
List<SalesOrderCommand> salesOrderPage = sdkOrderDao.findOrdersWithOutPage(sorts, searchParam);
//...
List<Long> idList = new ArrayList<>(salesOrderPage.size());
for (SalesOrderCommand cmd : salesOrderPage){
idList.add(cmd.getId());
}
//查询订单行
List<OrderLineCommand> allLineList = sdkOrderLineDao.findOrderDetailListByOrderIds(idList);
这段代码,可以一行代码搞定
List<SalesOrderCommand> salesOrderPage = sdkOrderDao.findOrdersWithOutPage(sorts, searchParam);
//...
List<Long> idList =CollectionsUtil.getPropertyValueList(salesOrderPage, "id");
//查询订单行
List<OrderLineCommand> allLineList = sdkOrderLineDao.findOrderDetailListByOrderIds(idList);
PS: 相似的方法,还有 CollectionsUtil.getPropertyValueSet(Collection<O>, String)
以及 CollectionsUtil.getPropertyValueMap(Collection<O>, String, String)
2.不能不说的异常处理
众所周知,JAVA 有 checked exception
和 uncheckedException
之分,也就是我们常说的 RuntimeException
和 Exception
checked exception
有其使用场景,但是我们日常开发过程中,并没有对他做特殊的代码处理
比如,大部分小伙伴的代码是这样的:
public ContactCommand toContactCommand(ContactCommand command) {
try {
BeanUtils.copyProperties(command, this);
} catch (Exception e){
LOGGER.error("", e);
//or e.printStackTrace();
}
return command;
}
其实细究下来,上述代码是不合理的, 如果转换的时候出现了异常,这里就会出现数据没有转换过去的情况,
这理论上是 RuntimeException
,但是 org.apache.commons.beanutils.BeanUtils
里面使用的是Exception
, 所以小伙伴不能不try… catch
一下,可是 catch 代码里面有可能仅仅写了log记录,这有可能会出现逻辑问题 (本来需要抛出异常让事务回滚)
这时可以使用 com.feilong.core.bean.BeanUtil
public ContactCommand toContactCommand(ContactCommand command){
com.feilong.core.bean.BeanUtil.copyProperties(command, this);
return command;
}
当然,如果你确定copy的对象相同属性名称的类型是一致
的, 你可以使用 PropertyUtil
,可以有效的避免不必要的类型转换,提高效率
代码简洁,而且内部包装成的是自定义的 BeanOperationException
(RuntimeException
),如果需要特殊处理,依然可以 try…catch…
3. 有丰富的javadoc
调用方法的时候,可以清晰的感知这个方法的 作用
,示例
,说明点
,参数
,返回值
,异常
等信息
源码示例:
/**
* 计算两个时间相差的的天数(<span style="color:red">绝对值</span>).
*
* <h3>说明:</h3>
* <blockquote>
* <p>
* 值=两个时间相差毫秒的绝对值/{@link TimeInterval#MILLISECOND_PER_DAY}
* </p>
* </blockquote>
*
* <h3>示例:</h3>
*
* <blockquote>
*
* <pre class="code">
* DateExtensionUtil.getIntervalDay(
* toDate("2008-08-24",COMMON_DATE),
* toDate("2008-08-27",COMMON_DATE)) = 3
*
* DateExtensionUtil.getIntervalDay(
* toDate("2016-08-21 12:00:00",COMMON_DATE_AND_TIME),
* toDate("2016-08-22 11:00:00",COMMON_DATE_AND_TIME)) = 0
*
* DateExtensionUtil.getIntervalDay(
* toDate("2016-08-21",COMMON_DATE),
* toDate("2016-08-22",COMMON_DATE)) = 1
*
* DateExtensionUtil.getIntervalDay(
* toDate("2016-02-28",COMMON_DATE),
* toDate("2016-03-02",COMMON_DATE)) = 3
*
* DateExtensionUtil.getIntervalDay(
* toDate("2016-08-31",COMMON_DATE),
* toDate("2016-09-02",COMMON_DATE)) = 2
*
* </pre>
*
* </blockquote>
*
* @param date1
* date1
* @param date2
* date2
* @return 如果 <code>date1</code> 是null,抛出 {@link NullPointerException}<br>
* 如果 <code>date2</code> 是null,抛出 {@link NullPointerException}
* @see #getIntervalTime(Date, Date)
* @see #getIntervalDay(long)
* @since 1.6.0
*/
public static int getIntervalDay(Date date1,Date date2){
return getIntervalDay(getIntervalTime(date1, date2));
}
如果你使用maven的话,只需要在依赖的jar 右键, maven—> download javadoc
或者 download sources
会自动下载
4. 每个方法均有完善的 junit test
方法实现之后,有上述的javadoc 详细的描述这个方法的作用 特点,注意点等, 那么怎么证明你写的东西都是正确而胡编乱造的呢?
我们有详细的 junit
单元测试, 每次构建的时候,都会经过maven 的单元测试周期
比如 MapUtilGetSubMapTest
package com.feilong.core.util.maputiltest;
import static java.util.Collections.emptyMap;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import com.feilong.core.util.MapUtil;
public class MapUtilGetSubMapTest{
/**
* Test get sub map.
*/
@Test
public void testGetSubMap(){
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("a", 3007);
map.put("b", 3001);
map.put("c", 3001);
map.put("d", 3003);
Map<String, Integer> subMap = MapUtil.getSubMap(map, "a", "c");
assertThat(subMap, allOf(hasEntry("a", 3007), hasEntry("c", 3001), not(hasKey("b")), not(hasKey("d"))));
}
/**
* Test get sub map 1.
*/
@Test
public void testGetSubMap1(){
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("a", 3007);
map.put("b", 3001);
map.put("c", 3001);
map.put("d", 3003);
Map<String, Integer> subMap = MapUtil.getSubMap(map, "a", "c", "f");
assertThat(subMap, allOf(hasEntry("a", 3007), hasEntry("c", 3001), not(hasKey("b")), not(hasKey("d"))));
}
/**
* Test get sub map null keys.
*/
@Test
public void testGetSubMapNullKeys(){
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("a", 3007);
map.put("b", 3001);
map.put("c", 3001);
map.put("d", 3003);
assertEquals(map, MapUtil.getSubMap(map, null));
}
/**
* Test get sub map empty keys.
*/
@Test
public void testGetSubMapEmptyKeys(){
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("a", 3007);
map.put("b", 3001);
map.put("c", 3001);
map.put("d", 3003);
assertEquals(map, MapUtil.getSubMap(map));
}
/**
* Test get sub map null map.
*/
@Test
public void testGetSubMapNullMap(){
assertEquals(emptyMap(), MapUtil.getSubMap(null, "a", "c"));
}
/**
* Test get sub map empty map.
*/
@Test
public void testGetSubMapEmptyMap(){
assertEquals(emptyMap(), MapUtil.getSubMap(new HashMap<>(), "a", "c"));
assertEquals(emptyMap(), MapUtil.getSubMap(emptyMap(), "a", "c"));
}
}