Java 编程技巧之数据结构



翁取一葫芦置于地,以钱覆其口,徐以杓酌油沥之,自钱孔入,而钱不湿。因曰:“我亦无他,唯手熟尔。”

/**?查找第一个重复字符?*/
public?static?char?findFirstRepeatedChar(String?string)?{
???//?检查空字符串
???if?(Objects.isNull(string)?||?string.isEmpty())?{
???????return?null;
??}
???//?查找重复字符
???char[]?charArray?=?string.toCharArray();
???Set?charSet?=?new?HashSet<>(charArray.length);
???for?(char?ch?:?charArray)?{
???????if?(charSet.contains(ch))?{
???????????return?ch;
??????}
???????charSet.add(ch);
??}
???//?默认返回为空
???return?null;
}
if?(!charSet.add(ch))?{
???return?ch;
}

/**?菜单DO类?*/
@Setter
@Getter
@ToString
public?static?class?MenuDO?{
???/**?菜单标识?*/
???private?Long?id;
???/**?菜单父标识?*/
???private?Long?parentId;
???/**?菜单名称?*/
???private?String?name;
???/**?菜单链接?*/
???private?String?url;
}
/**?菜单VO类?*/
@Setter
@Getter
@ToString
public?static?class?MenuVO?{
???/**?菜单标识?*/
???private?Long?id;
???/**?菜单名称?*/
???private?String?name;
???/**?菜单链接?*/
???private?String?url;
???/**?子菜单列表?*/
???private?List?childList;
}
/**?构建菜单树函数?*/
public?static?List ?buildMenuTree(List?menuList)?{
???//?检查列表为空
???if?(CollectionUtils.isEmpty(menuList))?{
???????return?Collections.emptyList();
??}
???//?依次处理菜单
???int?menuSize?=?menuList.size();
???List?rootList?=?new?ArrayList<>(menuSize);
???Map?menuMap?=?new?HashMap<>(menuSize);
???for?(MenuDO?menuDO?:?menuList)?{
???????//?赋值菜单对象
???????Long?menuId?=?menuDO.getId();
???????MenuVO?menu?=?menuMap.get(menuId);
???????if?(Objects.isNull(menu))?{
???????????menu?=?new?MenuVO();
???????????menu.setChildList(new?ArrayList<>());
???????????menuMap.put(menuId,?menu);
??????}
???????menu.setId(menuDO.getId());
???????menu.setName(menuDO.getName());
???????menu.setUrl(menuDO.getUrl());
???????//?根据父标识处理
???????Long?parentId?=?menuDO.getParentId();
???????if?(Objects.nonNull(parentId))?{
???????????//?构建父菜单对象
???????????MenuVO?parentMenu?=?menuMap.get(parentId);
???????????if?(Objects.isNull(parentMenu))?{
???????????????parentMenu?=?new?MenuVO();
???????????????parentMenu.setId(parentId);
???????????????parentMenu.setChildList(new?ArrayList<>());
???????????????menuMap.put(parentId,?parentMenu);
??????????}
???????????//?添加子菜单对象
???????????parentMenu.getChildList().add(menu);
??????}?else?{
???????????//?添加根菜单对象
???????????rootList.add(menu);
??????}
??}
???//?返回根菜单列表
???return?rootList;
}
/**?分页方法类?*/
public?abstract?class?PageMethod?{
???/**?本地分页?*/
???protected?static?final?ThreadLocal?LOCAL_PAGE?=?new?ThreadLocal ();
???/**?设置分页参数?*/
???protected?static?void?setLocalPage(Page?page)?{
???????LOCAL_PAGE.set(page);
??}
???/**?获取分页参数?*/
???public?static??Page?getLocalPage()? {
???????return?LOCAL_PAGE.get();
??}
???/**?开始分页?*/
???public?static??Page?startPage(int?pageNum,?int?pageSize,?boolean?count,?Boolean?reasonable,?Boolean?pageSizeZero)? {
???????Page ?page?=?new?Page (pageNum,?pageSize,?count);
???????page.setReasonable(reasonable);
???????page.setPageSizeZero(pageSizeZero);
???????Page ?oldPage?=?getLocalPage();
???????if?(oldPage?!=?null?&&?oldPage.isOrderByOnly())?{
???????????page.setOrderBy(oldPage.getOrderBy());
??????}
???????setLocalPage(page);
???????return?page;
??}
}
/**?虚辅助方言类?*/
public?abstract?class?AbstractHelperDialect?extends?AbstractDialect?implements?Constant?{
???/**?获取本地分页?*/
???public??Page ?getLocalPage()?{
???????return?PageHelper.getLocalPage();
??}
???/**?获取分页SQL?*/
???@Override
???public?String?getPageSql(MappedStatement?ms,?BoundSql?boundSql,?Object?parameterObject,?RowBounds?rowBounds,?CacheKey?pageKey)?{
???????String?sql?=?boundSql.getSql();
???????Page?page?=?getLocalPage();
???????String?orderBy?=?page.getOrderBy();
???????if?(StringUtil.isNotEmpty(orderBy))?{
???????????pageKey.update(orderBy);
???????????sql?=?OrderByParser.converToOrderBySql(sql,?orderBy);
??????}
???????if?(page.isOrderByOnly())?{
???????????return?sql;
??????}
???????return?getPageSql(sql,?page,?pageKey);
??}
??...
}
/**?查询用户函数?*/
public?PageInfo?queryUser(UserQuery?userQuery,?int?pageNum,?int?pageSize)? {
?PageHelper.startPage(pageNum,?pageSize);
?List?userList?=?userDAO.queryUser(userQuery);
?PageInfo ?pageInfo?=?new?PageInfo<>(userList);
?return?pageInfo;
}
/**?日期模式?*/
private?static?final?String?DATE_PATTERN?=?"yyyy-MM-dd";
/**?格式化日期函数?*/
public?static?String?formatDate(Date?date)?{
???return?new?SimpleDateFormat(DATE_PATTERN).format(date);
}
/**?日期格式?*/
private?static?final?DateFormat?DATE_FORMAT?=?new?SimpleDateFormat("yyyy-MM-dd");
/**?格式化日期函数?*/
public?static?String?formatDate(Date?date)?{
???return?DATE_FORMAT.format(date);
}
/**?本地日期格式?*/
private?static?final?ThreadLocal?LOCAL_DATE_FORMAT?=?new?ThreadLocal ()?{
???@Override
???protected?DateFormat?initialValue()?{
???????return?new?SimpleDateFormat("yyyy-MM-dd");
??}
};
/**?格式化日期函数?*/
public?static?String?formatDate(Date?date)?{
???return?LOCAL_DATE_FORMAT.get().format(date);
}

/**?点和距离类?*/
@Setter
@Getter
@ToString
@AllArgsConstructor
public?static?class?PointAndDistance?{
???/**?点?*/
???private?Point?point;
???/**?距离?*/
???private?Double?distance;
}
/**?获取最近点和距离?*/
public?static?PointAndDistance?getNearestPointAndDistance(Point?point,?Point[]?points)?{
???//?检查点数组为空
???if?(ArrayUtils.isEmpty(points))?{
???????return?null;
??}
???//?获取最近点和距离
???Point?nearestPoint?=?points[0];
???double?nearestDistance?=?getDistance(point,?points[0]);
???for?(int?i?=?1;?i?< ?points.length;?i++)?{
???????double?distance?=?getDistance(point,?point[i]);
???????if?(distance?< ?nearestDistance)?{
???????????nearestDistance?=?distance;
???????????nearestPoint?=?point[i];
??????}
??}
???//?返回最近点和距离
???return?new?PointAndDistance(nearestPoint,?nearestDistance);
}
Point?point?=?...;
Point[]?points?=?...;
PointAndDistance?pointAndDistance?=?getNearestPointAndDistance(point,?points);
if?(Objects.nonNull(pointAndDistance))?{
???Point?point?=?pointAndDistance.getPoint();
???Double?distance?=?pointAndDistance.getDistance();
??...
}
/**?获取最近点和距离?*/
public?static?Pair?getNearestPointAndDistance(Point?point,?Point[]?points)? {
???//?检查点数组为空
???if?(ArrayUtils.isEmpty(points))?{
???????return?null;
??}
???//?获取最近点和距离
???Point?nearestPoint?=?points[0];
???double?nearestDistance?=?getDistance(point,?points[0]);
???for?(int?i?=?1;?i?< ?points.length;?i++)?{
???????double?distance?=?getDistance(point,?point[i]);
???????if?(distance?< ?nearestDistance)?{
???????????nearestDistance?=?distance;
???????????nearestPoint?=?point[i];
??????}
??}
???//?返回最近点和距离
???return?Pair.of(nearestPoint,?nearestDistance);
}
Point?point?=?...;
Point[]?points?=?...;
Pair?pair?=?getNearestPointAndDistance(point,?points);
if?(Objects.nonNull(pair))?{
???Point?point?=?pair.getLeft();
???Double?distance?=?pair.getRight();
??...
}

/**?订单状态枚举?*/
public?final?class?OrderStatus?{
???/**?属性相关?*/
???/**?状态取值?*/
???private?final?int?value;
???/**?状态描述?*/
???private?final?String?description;
???/**?常量相关?*/
???/**?已创建(1)?*/
???public?static?final?OrderStatus?CREATED?=?new?OrderStatus(1,?"已创建");
???/**?进行中(2)?*/
???public?static?final?OrderStatus?PROCESSING?=?new?OrderStatus(2,?"进行中");
???/**?已完成(3)?*/
???public?static?final?OrderStatus?FINISHED?=?new?OrderStatus(3,?"已完成");
???/**?构造函数?*/
???private?OrderStatus(int?value,?String?description)?{
???????this.value?=?value;
???????this.description?=?description;
??}
???/**?获取状态取值?*/
???public?int?getValue()?{
???????return?value;
??}
???/**?获取状态描述?*/
???public?String?getDescription()?{
???????return?description;
??}
}
/**?订单状态枚举?*/
public?enum?OrderStatus?{
???/**?常量相关?*/
???/**?已创建(1)?*/
???CREATED(1,?"已创建"),
???/**?进行中(2)?*/
???PROCESSING(2,?"进行中"),
???/**?已完成(3)?*/
???FINISHED(3,?"已完成");
???/**?属性相关?*/
???/**?状态取值?*/
???private?final?int?value;
???/**?状态描述?*/
???private?final?String?description;
???/**?构造函数?*/
???private?OrderStatus(int?value,?String?description)?{
???????this.value?=?value;
???????this.description?=?description;
??}
???/**?获取状态取值?*/
???public?int?getValue()?{
???????return?value;
??}
???/**?获取状态描述?*/
???public?String?getDescription()?{
???????return?description;
??}
}

/**?长整型支撑类?*/
@Getter
@Setter
@ToString
public?class?LongHolder?{
???/**?长整型取值?*/
???private?long?value;
???/**?构造函数?*/
???public?LongHolder()?{}
???/**?构造函数?*/
???public?LongHolder(long?value)?{
???????this.value?=?value;
??}
}
/**?静态常量?*/
/**?页面数量?*/
private?static?final?int?PAGE_COUNT?=?100;
/**?最大数量?*/
private?static?final?int?MAX_COUNT?=?1000;
/**?处理过期订单?*/
public?void?handleExpiredOrder()?{
??LongHolder?minIdHolder?=?new?LongHolder(0L);
????for?(int?pageIndex?=?0;?pageIndex?< ?PAGE_COUNT;?pageIndex++)?{
????????if?(!handleExpiredOrder(pageIndex,?minIdHolder))?{
??????????break;
????????}
????}
}
/**?处理过期订单?*/
private?boolean?handleExpiredOrder(int?pageIndex,?LongHolder?minIdHolder)?{
??//?获取最小标识
??Long?minId?=?minIdHolder.getValue();
??//?查询过期订单(按id从小到大排序)
??List?orderList?=?orderDAO.queryExpired(minId,?MAX_COUNT);
??if?(CollectionUtils.isEmpty(taskTagList))?{
????return?false;
??}
??//?设置最小标识
??int?orderSize?=?orderList.size();
??minId?=?orderList.get(orderSize?-?1).getId();
??minIdHolder.setValue(minId);
??//?依次处理订单
???for?(OrderDO?order?:?orderList)?{
???????...
????}
??//?判断还有订单
??return?orderSize?>=?PAGE_SIZE;
}

/**?客户消息类?*/
@ToString
public?class?CustomerMessage?{
???/**?属性相关?*/
???/**?消息类型?*/
???private?String?msgType;
???/**?目标用户?*/
???private?String?toUser;
???/**?共用体相关?*/
???/**?新闻内容?*/
???private?News?news;
??...
???/**?常量相关?*/
???/**?新闻消息?*/
???public?static?final?String?MSG_TYPE_NEWS?=?"news";
??...
???/**?构造函数?*/
???public?CustomerMessage()?{}
???/**?构造函数?*/
???public?CustomerMessage(String?toUser)?{
???????this.toUser?=?toUser;
??}
???/**?构造函数?*/
???public?CustomerMessage(String?toUser,?News?news)?{
???????this.toUser?=?toUser;
???????this.msgType?=?MSG_TYPE_NEWS;
???????this.news?=?news;
??}
???/**?清除消息内容?*/
???private?void?removeMsgContent()?{
???????//?检查消息类型
???????if?(Objects.isNull(msgType))?{
???????????return;
??????}
???????//?清除消息内容
???????if?(MSG_TYPE_NEWS.equals(msgType))?{
???????????news?=?null;
??????}?else?if?(...)?{
??????...
}
???????msgType?=?null;
??}
???/**?检查消息类型?*/
???private?void?checkMsgType(String?msgType)?{
???????//?检查消息类型
???????if?(Objects.isNull(msgType))?{
???????????throw?new?IllegalArgumentException("消息类型为空");
??????}
???????//?比较消息类型
???????if?(!Objects.equals(msgType,?this.msgType))?{
???????????throw?new?IllegalArgumentException("消息类型不匹配");
??????}
??}
???/**?设置消息类型函数?*/
???public?void?setMsgType(String?msgType)?{
???????//?清除消息内容
???????removeMsgContent();
???????//?检查消息类型
???????if?(Objects.isNull(msgType))?{
???????????throw?new?IllegalArgumentException("消息类型为空");
??????}
???????//?赋值消息内容
???????this.msgType?=?msgType;
???????if?(MSG_TYPE_NEWS.equals(msgType))?{
???????????news?=?new?News();
??????}?else?if?(...)?{
??????...
??????}?else?{
???????????throw?new?IllegalArgumentException("消息类型不支持");
??????}
??}
???/**?获取消息类型?*/
???public?String?getMsgType()?{
???????//?检查消息类型
???????if?(Objects.isNull(msgType))?{
???????????throw?new?IllegalArgumentException("消息类型无效");
??????}
???????//?返回消息类型
???????return?this.msgType;
??}
???/**?设置新闻?*/
???public?void?setNews(News?news)?{
???????//?清除消息内容
???????removeMsgContent();
???????//?赋值消息内容
???????this.msgType?=?MSG_TYPE_NEWS;
???????this.news?=?news;
??}
???/**?获取新闻?*/
???public?News?getNews()?{
???????//?检查消息类型
???????checkMsgType(MSG_TYPE_NEWS);
???????//?返回消息内容
???????return?this.news;
??}
??...
}
String?accessToken?=?...;
String?toUser?=?...;
List?articleList?=?...;
News?news?=?new?News(articleList);
CustomerMessage?customerMessage?=?new?CustomerMessage(toUser,?news);
wechatApi.sendCustomerMessage(accessToken,?customerMessage);
优点:更贴近 C/C++ 语言的联合体(union);
缺点:实现逻辑较为复杂,参数类型验证较多。
/**?客户消息类?*/
@Getter
@Setter
@ToString
public?abstract?class?CustomerMessage?{
???/**?属性相关?*/
???/**?消息类型?*/
???private?String?msgType;
???/**?目标用户?*/
???private?String?toUser;
???/**?常量相关?*/
???/**?新闻消息?*/
???public?static?final?String?MSG_TYPE_NEWS?=?"news";
??...
???/**?构造函数?*/
???public?CustomerMessage(String?msgType)?{
???????this.msgType?=?msgType;
??}
???/**?构造函数?*/
???public?CustomerMessage(String?msgType,?String?toUser)?{
???????this.msgType?=?msgType;
???????this.toUser?=?toUser;
??}
}
/**?新闻客户消息类?*/
@Getter
@Setter
@ToString(callSuper?=?true)
public?class?NewsCustomerMessage?extends?CustomerMessage?{
???/**?属性相关?*/
???/**?新闻内容?*/
???private?News?news;
???/**?构造函数?*/
???public?NewsCustomerMessage()?{
???????super(MSG_TYPE_NEWS);
??}
???/**?构造函数?*/
???public?NewsCustomerMessage(String?toUser,?News?news)?{
???????super(MSG_TYPE_NEWS,?toUser);
???????this.news?=?news;
??}
}
String?accessToken?=?...;
String?toUser?=?...;
List?articleList?=?...;
News?news?=?new?News(articleList);
CustomerMessage?customerMessage?=?new?NewsCustomerMessage(toUser,?news);
wechatApi.sendCustomerMessage(accessToken,?customerMessage);
优点:使用虚基类和子类进行拆分,各个子类对象的概念明确;
缺点:与 C/C++ 语言的联合体(union)差别大,但是功能上大体一致。

/**?通用支撑类?*/
@Getter
@Setter
@ToString
public?class?GenericHolder?{
???/**?通用取值?*/
???private?T?value;
???/**?构造函数?*/
???public?GenericHolder()?{}
???/**?构造函数?*/
???public?GenericHolder(T?value)?{
???????this.value?=?value;
??}
}
/**?数据提供者接口?*/
public?interface?DataProvider< T>?{
???/**?获取数据函数?*/
???public?T?getData();
}
/**?浅拷贝函数?*/
public?static??T?shallowCopy(Object?source,?Class< T>?clazz)?throws?BeansException?{
???//?判断源对象
???if?(Objects.isNull(source))?{
???????return?null;
??}
???//?新建目标对象
???T?target;
???try?{
???????target?=?clazz.newInstance();
??}?catch?(Exception?e)?{
???????throw?new?BeansException("新建类实例异常",?e);
??}
???//?拷贝对象属性
???BeanUtils.copyProperties(source,?target);
???//?返回目标对象
???return?target;
}
/**?打印取值函数?*/
public?static?void?printValue(GenericHolder< ?>?holder)?{
???System.out.println(holder.getValue());
}
/**?主函数?*/
public?static?void?main(String[]?args)?{
???printValue(new?GenericHolder<>(12345));
???printValue(new?GenericHolder<>("abcde"));
}
/**?打印取值函数?*/
public?static??void?printValue(GenericHolder?holder )?{
???System.out.println(holder.getValue());
}
/**?数字支撑类?*/
@Getter
@Setter
@ToString
public?class?NumberHolder?{
???/**?通用取值?*/
???private?T?value;
???/**?构造函数?*/
???public?NumberHolder()?{}
???/**?构造函数?*/
???public?NumberHolder(T?value)?{
???????this.value?=?value;
??}
}
/**?打印取值函数?*/
public?static??void?printValue(GenericHolder?holder) ?{
???System.out.println(holder.getValue());
}

CSDN 博客诚邀入驻啦!
本着共享、协作、开源、技术之路我们共同进步的准则,
只要你技术够干货,内容够扎实,分享够积极,
欢迎加入 CSDN 大家庭!
扫描下方二维码,即刻加入吧!

?热 文?推 荐?
?花了 4 天,破解 UNIX 联合创始人 39 年前的密码!
?估值被砍700亿美元后,Waymo发重磅公开信:即将推出全自动驾驶打车服务
?2019年胡润百富榜发布,比特大陆创始人詹克团成「中国区块链首富」!
点击阅读原文,输入关键词,即可搜索您想要的 CSDN 文章。

关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
关注网络尖刀微信公众号随时掌握互联网精彩
赞助链接
排名
热点
搜索指数
- 1 习近平听取岑浩辉述职报告 7903939
- 2 哈尔滨大雪人原来是挖出来的 7808060
- 3 央视曝光走私孕妇血样黑色产业链 7713002
- 4 2025年度文化记忆 重温感动瞬间 7618846
- 5 女子毛衣粘走3000元翡翠耳环主动归还 7519735
- 6 中央财办:扩大内需是明年首位任务 7424077
- 7 学校通报“宿管摔死学生小猫” 7330075
- 8 美军拟进行重大军事改革 7232353
- 9 52岁民警处置高速事故被撞身亡 7137877
- 10 用漫画方式了解海南自贸港封关 7042489







CSDN
