java的TreeMap在ip转区域的使用
来源:互联网 发布:数据库系统的构成 编辑:程序博客网 时间:2024/04/30 15:12
前段时间 有个统计的需求,有用户的登陆IP,想转成市,然后用于统计。几百万的数据拿来网上查还是慢了些,于是就找一些批量,或者本地的处理方法
有两个方案是备选的:
一、
这边的一个同事提供了一个文件(不清楚哪里搞来的),里面有ipbegin-ipEnd 地市,省 这些字段,用了10来个ip 测试,还是靠谱,格式如下
1551@@1.189.24.0@@1.189.24.255@@黑龙江省哈尔滨市通河县@@联通@@黑龙江省@@哈尔滨市@@HL1561@@1.189.247.0@@1.189.248.255@@黑龙江省哈尔滨市延寿县@@联通@@黑龙江省@@哈尔滨市@@HL1571@@1.189.249.0@@1.189.250.255@@黑龙江省哈尔滨市双城区@@联通@@黑龙江省@@哈尔滨市@@HL1581@@1.189.25.0@@1.189.30.255@@黑龙江省哈尔滨市@@联通@@黑龙江省@@哈尔滨市@@HL1591@@1.189.251.0@@1.189.254.255@@黑龙江省哈尔滨市@@联通@@黑龙江省@@哈尔滨市@@HL
二、
http://www.ipip.net这个地址,有ip库下载,也提供了各语言的api例子.
后来考虑了下,第一个方案,数据都是现成的,比较有安全感,就选择自己去解析。
具体处理
整个文件有40W行数据,用循环查找是太慢了,考虑到ip有大小之分,于是决定用树.
设计思路
一条数据一个节点,利用大小比较, 构建成平衡树,查找的时候,一个 ip,如果小于ip_begin,则往一个方向,如果大于ip_end 则另一方向,如果在begin和end中间,则此节点为目标节点.
程序设计
java里面有treeMap,把节点扔进去,其自己会构建成一棵树,当然,此节点要实现 compareTo
的方法,把节点和ip的大小比较出来.
除了ip_begin,和ip_end , 此entity 上也加上 targetip用于通过ip取节点时的比较
具体代码
两个类是核心的
- TipRange
compareTo方法是关键
public class TipRange implements Comparable<TipRange> { private Integer id; // ipBegin private String ipBegin; // ipEnd private String ipEnd; private String regiondesc; private String typedesc; private String province; private String city; private String provinceCode; private Date updatetime; private String targetip; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getIpBegin() { return ipBegin; } public void setIpBegin(String ipBegin) { this.ipBegin = ipBegin; } public String getIpEnd() { return ipEnd; } public void setIpEnd(String ipEnd) { this.ipEnd = ipEnd; } public String getRegiondesc() { return regiondesc; } public void setRegiondesc(String regiondesc) { this.regiondesc = regiondesc; } public String getTypedesc() { return typedesc; } public void setTypedesc(String typedesc) { this.typedesc = typedesc; } public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getProvinceCode() { return provinceCode; } public void setProvinceCode(String provinceCode) { this.provinceCode = provinceCode; } public Date getUpdatetime() { return updatetime; } public void setUpdatetime(Date updatetime) { this.updatetime = updatetime; } public String getTargetip() { return targetip; } public void setTargetip(String targetip) { this.targetip = targetip; } @Override public int compareTo(TipRange targetRange) { String paramIp = targetRange.getTargetip(); if(StringUtils.isEmpty(paramIp)&&StringUtils.isEmpty(this.getTargetip())){ //两个都没ip为空,说明range和range对比 long currtntipbeginLong = IpRangeUtil.ipStrToLong(ipBegin); long currentipendLong = IpRangeUtil.ipStrToLong(ipEnd); long rangeBegin = IpRangeUtil.ipStrToLong(targetRange.getIpBegin()); if(rangeBegin<currtntipbeginLong){ return 1; }else if (rangeBegin==currtntipbeginLong){ return 0; }else{ return -1; } } if(StringUtils.isNotEmpty(paramIp)&&StringUtils.isEmpty(this.getTargetip())){ ////两个都没ip为空,说明range和range对比 long targetIpLong = IpRangeUtil.ipStrToLong(paramIp); long currtntipbeginLong = IpRangeUtil.ipStrToLong(ipBegin); long currentipendLong = IpRangeUtil.ipStrToLong(ipEnd); //判断目标要往哪走 if(targetIpLong<currtntipbeginLong){ return 1; }else if (targetIpLong>currentipendLong){ return -1; }else{ return 0; } } if(StringUtils.isEmpty(paramIp)&&StringUtils.isNotEmpty(this.getTargetip())){ //两个都没ip为空,说明range和range对比 long currentIpLong = IpRangeUtil.ipStrToLong(this.getTargetip()); long targetBeginLong = IpRangeUtil.ipStrToLong(targetRange.getIpBegin()); long targetEndLong = IpRangeUtil.ipStrToLong(targetRange.getIpEnd()); //判断目标要往哪走 if(currentIpLong<targetBeginLong){ return -1; }else if (currentIpLong>targetEndLong){ return 1; }else{ return 0; } } return -2; }}
- TgipRangeServiceImpl
取数据,扔到treemap,其 ipToAddress 方法即为 暴露的api
import com.yp.springboot.util.FileReadUtils;import com.yp.springboot.util.IFileOperByLine;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.RowMapper;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import java.io.File;import java.sql.Date;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import java.util.List;import java.util.Map;import java.util.TreeMap;@Servicepublic class TgipRangeServiceImpl {private static Map<TipRange, TipRange> cacheIpRangeMap;@Autowired public JdbcTemplate jdbcTemplate;private static Logger logger = LoggerFactory.getLogger("rlog");public List<TipRange> queryAllByFile() throws Exception{File file = new File("E:\\codeplace\\n_learn\\java\\springboot\\myexample\\springbootweb\\src\\main\\resources\\regionip.txt");// final List<TipRange> iprangeList1 = new ArrayList();FileReadUtils.readFileAndUnionObj(file, new IFileOperByLine() {@Override public void toOperLineNoList(String fileName, String linestr) {String[] arrayText = linestr.split("@@");Integer id = Integer.valueOf(arrayText[0]);String ipBegin = arrayText[1];String ipEnd = arrayText[2];String regiondesc = arrayText[3];String typedesc = arrayText[4];String province = arrayText[5];String city = arrayText[6];String provinceCode = arrayText[7];TipRange tmp = new TipRange();tmp.setId(id);tmp.setIpBegin(ipBegin);tmp.setIpEnd(ipEnd);tmp.setRegiondesc(regiondesc);tmp.setTypedesc(typedesc);tmp.setProvince(province);tmp.setCity(city);tmp.setProvinceCode(provinceCode);//处理 iprangeList1.add(tmp);}});return iprangeList1;}/** * * @return */ @Transactional(propagation = Propagation.NOT_SUPPORTED)protected Map<TipRange, TipRange> genIpRangeToLogAllMap() throws Exception {Map<TipRange, TipRange> allMap = new TreeMap<TipRange, TipRange>();List<TipRange> allList = queryAllByFile();for (TipRange entityRange : allList) {allMap.put(entityRange, entityRange);}return allMap;}private String toTrim(String sstr){if(sstr==null)return "";return sstr.trim();}@Transactional(propagation = Propagation.NOT_SUPPORTED)private synchronized void initMap() throws Exception {cacheIpRangeMap = genIpRangeToLogAllMap();}/* */ @Transactional(propagation = Propagation.NOT_SUPPORTED)public TipRange ipToAddress(String ip) throws Exception {synchronized (this) {if (cacheIpRangeMap == null) {initMap();}}TipRange tmp = new TipRange();tmp.setTargetip(ip);return cacheIpRangeMap.get(tmp);}}
说明:
代码 :https://github.com/huawumingguo/springbootsample/tree/master/springbootweb
0 0
- java的TreeMap在ip转区域的使用
- Java中treeMap的使用。。
- java TreeMap排序的使用
- Java中treeMap的使用
- TreeMap的使用
- TreeMap的使用
- TreeMap类的使用
- TreeMap的使用
- treeMap的使用
- Java TreeMap的排序
- Java TreeMap的排序
- java TreeMap的用法
- java的TreeMap类
- Java TreeMap的排序
- java的TreeMap
- Java TreeMap的排序(转)
- TreeMap的使用及注意事项
- TreeMap<K,V>的使用
- Java首字母大写
- 在网页上能在线编辑的html标签
- bzoj2434 [Noi2011]阿狸的打字机
- react-navigation之动态修改title的内容
- 基于DirectUI技术开发的发卡系统
- java的TreeMap在ip转区域的使用
- 弹出框页面居中显示的两种方法
- tensorflow center loss代码注释
- 史上最全的CSS hack方式一览
- 初识JHipster
- 接上--根据不同请求路径处理不同响应
- opencv图像阈值设置
- 马景涛手写长文宣布离婚 表示放飞妻女送上祝福十分咆哮
- Akka TypedActor