IP地址 归属地查询

目标

通过开发IP地址归属地查询平台,我们需要对JavaSE综合技术有所提升,增强实战能力。学习完该项目我们应该具备如下能力:

1 面向对象程序设计

2 工具类封装与使用写法

3 文件IO流

4 字符串处理

5 二分法查找

6 IP地址的不同形式的使用

思路

1 程序中读取内容

2 解析IP字符串,进行结构化处理

3 封装工具类

4 接口API

入参 : IP

出参 : 归属地

代码开发

读取文件

public static List<String>getLineList(String filePath,String encoding)throws IOException{
		//节点流对接文件
		FileInputStream fis=new FileInputStream(filePath);
		//转换为字符 并指定字符编码 
		Reader reader=new InputStreamReader(fis,encoding);
		//缓冲流提高效率
		BufferedReader br=new BufferedReader(reader);
		//读取
		String line=null;
		//保存读取的数据
		List<String>lineList=new ArrayList<String>();
		while((line=br.readLine())!=null){
			//添加到集合中
			lineList.add(line);
		}
		//关闭
		br.close();
		return lineList;

 

 结构化ip地址实体类
 * 
 *
 */
public class IPAndLocationPojo implements Comparable<IPAndLocationPojo>{
	//衍生字段 用于保存ip对应的long值
	private long startIPLong;
	private long endIPLong;
	//起始IP
	private String startIP;
	//结束IP
	private String endIP;
	//归属地
	private String location;
	 public int compareTo(IPAndLocationPojo o){
		 long status=this.startIPLong-o.startIPLong;
		 //不能强制转换 如果两个值相差2127483647的话 转换为int之后 得到负数
		 //return(int)(this.start.IPLong-o.startIPLong);
		 return status>0?1:0;
	 }
	public IPAndLocationPojo(long startIPLong, long endIPLong, String startIP,
			String endIP, String location) {
		super();
		//对长整型赋值
		this.startIPLong = IPUtil.ipToLong(startIP);;
		this.endIPLong = IPUtil.ipToLong(endIP);;
		this.startIP = startIP;
		this.endIP = endIP;
		this.location = location;
	}
	public long getStartIPLong() {
		return startIPLong;
	}
	public void setStartIPLong(long startIPLong) {
		this.startIPLong = startIPLong;
	}
	public long getEndIPLong() {
		return endIPLong;
	}
	public void setEndIPLong(long endIPLong) {
		this.endIPLong = endIPLong;
	}
	public String getStartIP() {
		return startIP;
	}
	public void setStartIP(String startIP) {
		this.startIP = startIP;
	}
	public String getEndIP() {
		return endIP;
	}
	public void setEndIP(String endIP) {
		this.endIP = endIP;
	}
	public String getLocation() {
		return location;
	}
	public void setLocation(String location) {
		this.location = location;
	}
	public IPAndLocationPojo() {
		super();
		// TODO Auto-generated constructor stub
	}
	@Override
	public String toString() {
		return "IPAndLocationPojo [startIPLong=" + startIPLong + ", endIPLong="
				+ endIPLong + ", startIP=" + startIP + ", endIP=" + endIP
				+ ", location=" + location + "]";
	}

 

 程序核心业务类
 * 
 *
 */
public class DataProcessManager {
	private static IPAndLocationPojo[]ipAndLocationPojoArray=null;
	static{
		//文件路径
		String ipLibrayPath="ip_location_relation.txt";
		String encoding="UTF-8";
		//保存数据对象
		List<IPAndLocationPojo>ipAndLocationPojos=null;
		try {
			// 获取数据
			ipAndLocationPojos = DataProcessManager.getPojoList(ipLibrayPath,
					encoding);
			// 转数组并排序
			ipAndLocationPojoArray = DataProcessManager
					.convertListToArraySort(ipAndLocationPojos);

		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 对外提供的接口  入参是ip 出参是归属地
	 * @param ipAndLocationPojos
	 * @return
	 */
	public static String getLocation(String ip){
		//二分法查找
		int index=DataProcessManager.binaraySeach(ipAndLocationPojoArray, ip);
		// 判断是否找到
				if (index == -1) {
					return null;
				} else {
					return ipAndLocationPojoArray[index].getLocation();
				}
			}
	/**
	 * 二分法查找,入参是IP和数组,出参是对应的索引,找不到返回-1;
	 * @param ipAndLocationPojos
	 * @return
	 */
	public static int binaraySeach(IPAndLocationPojo[] ipAndLocationPojoArray,
			String targetIP) {
		// 把IP转换为long
		long targetIPLong = IPUtil.ipToLong(targetIP);
		int startIndex = 0;
		int endIndex = ipAndLocationPojoArray.length - 1;
		int m = (startIndex + endIndex) / 2;

		/**
		 * 如果 小于 起始IP 找前面
		 * 
		 * 如果 大于 起始IP 找后面
		 * 
		 * 如果 大于等于起始IP且 小于等于 结束IP 则说明找到了
		 */
		while (startIndex <= endIndex) {
			if (targetIPLong >= ipAndLocationPojoArray[m].getStartIPLong()
					&& targetIPLong <= ipAndLocationPojoArray[m].getEndIPLong()) {
				return m;
			}
			if (targetIPLong < ipAndLocationPojoArray[m].getStartIPLong()) {
				endIndex = m - 1;
			} else {
				startIndex = m + 1;
			}
			m = (startIndex + endIndex) / 2;
		}
		return -1;
	}
	//把集合转换为数组并排序
	public static IPAndLocationPojo[]convertListArraySort(List<IPAndLocationPojo>ipAndLocationPojos){
		//创建数组
		IPAndLocationPojo[]ipAndLocationPojoArray=new IPAndLocationPojo[ipAndLocationPojos.size()];
		//转换为数组
		ipAndLocationPojos.toArray(ipAndLocationPojoArray);
		//排序
		Arrays.sort(ipAndLocationPojoArray);
		return ipAndLocationPojoArray;
	}
	//结构化数据集合
	public static List<IPAndLocationPojo>getPojoList(String filePath,String encoding)throws IOException{
		//保存数据对象
		List<IPAndLocationPojo>ipAndLocationPojos=new ArrayList<IPAndLocationPojo>();
		List<String>lineList=FileOperatorUtil.getLineList(filePath, encoding);
		for(String string:lineList){
			//判断是否是空行
			if(string==null||string.trim().equals("")){
				continue;
			}
			//分割数组
			String[] columnArray=string.split("  ");
			//获取起始ip
			String startIP=columnArray[0];
			//获取结束ip
			String endIP=columnArray[1];
			//获取归属地
			String location=columnArray[2];
			//封装到对象中
			IPAndLocationPojo ipAndLocationPojo=new IPAndLocationPojo(startIP,endIP,location);
			//添加到集合中
			ipAndLocationPojos.add(ipAndLocationPojo);
			
		}
		return ipAndLocationPojos;
//入口
public class SystemController {
	@SuppressWarnings("resource")
	public static void main(String[] args) {
		// 接收用户输入
		Scanner scanner = new Scanner(System.in);
		while (true) {
			System.out.println("请输入IP地址 : ");
			String ip = scanner.nextLine();
			// 查询
			long startTime = System.currentTimeMillis();
			String location = DataProcessManager.getLocation(ip);
			long endTime = System.currentTimeMillis();
			System.out.println("耗时 : " + (endTime - startTime) + "  "
					+ location);

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值