1. 程式人生 > 實用技巧 >年齡使用128位二進位制字串進行儲存,這樣進行分段列舉時就可以保證,能夠快速靈活的標識每一段

年齡使用128位二進位制字串進行儲存,這樣進行分段列舉時就可以保證,能夠快速靈活的標識每一段

package test;

import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by zzq on 2020/11/27.
 */
public class RangeProcessor {
    private Map<String, List<Range>> mediaAgeRangeMap;

    
/** * 該建構函式期望應用首次啟動呼叫 * (非執行緒安全) * * @param rangeList */ public RangeProcessor(List<Range> rangeList) { if (rangeList == null) { throw new RuntimeException("rangeList不能為空"); } mediaAgeRangeMap = new HashMap<>(); for (int
i = 0; i < rangeList.size(); i++) { Range range = rangeList.get(i); range.initSegmentList(); List<Long> segmentList = range.getSegmentList(); if (segmentList == null || segmentList.size() == 0) { throw new RuntimeException("Range物件segmentList屬性不允許為空,請檢查Range#getBinRangeStr返回值是否為二進位制字串"); } String typeId
= range.getTypeId(); List<Range> innerRangeList = mediaAgeRangeMap.get(typeId); if (innerRangeList == null) { innerRangeList = new ArrayList<>(); mediaAgeRangeMap.put(typeId, innerRangeList); } innerRangeList.add(range); } } /** * 根據媒體id以及輸入的二進位制字串,獲取範圍標記列表,並升序排列 * (騰訊專用) * * @param typeId * @param binAgeRangeStr * @param tencent * @return * @throws Exception */ public List<String> getRangeTagList(String typeId, String binAgeRangeStr, boolean tencent) { checkBinAgeRange(binAgeRangeStr); if (tencent) {//處理騰訊邏輯 int startIndex = -1; int endIndex = -1; for (int i = 0; i < binAgeRangeStr.length(); i++) { char currChar = binAgeRangeStr.charAt(i); if (startIndex == -1 && currChar == 49) {//起始位置 endIndex = startIndex = i; } if (startIndex != -1 && currChar == 48) {//開始索引位置標記後,以0為標識尋找結束位置 endIndex = i - 1; break; } } List<String> retRangeTagList = new ArrayList<>(); retRangeTagList.add(startIndex + ""); retRangeTagList.add(endIndex + ""); return retRangeTagList; } return getRangeTagList(typeId, binAgeRangeStr); } /** * 根據媒體id以及輸入的二進位制字串,獲取範圍標記列表,並升序排列 * * @param typeId * @param binAgeRangeStr * @return */ public List<String> getRangeTagList(String typeId, String binAgeRangeStr) { checkBinAgeRange(binAgeRangeStr); if (mediaAgeRangeMap == null) { throw new RuntimeException("未呼叫AgeRangeProcessor建構函式"); } List<Range> rangeList = mediaAgeRangeMap.get(typeId); if (rangeList == null) { throw new RuntimeException("找不到typeId標識的區間,或未呼叫RangeProcessor建構函式"); } List<String> retAgeRangeNoList = new ArrayList<>(); for (int i = 0; i < rangeList.size(); i++) { Range range = rangeList.get(i); if (range.getBinRangeStr() == null || range.getBinRangeStr().length() != binAgeRangeStr.length()) { throw new RuntimeException("傳入的二進位制字串長度,與初始化的對比字串長度不同;或初始化字串為空,Range#getBinRangeStr方法不允許返回空"); } if (segmentCheck(range, binAgeRangeStr)) { retAgeRangeNoList.add(range.getRangeTag()); } } return retAgeRangeNoList; } private boolean segmentCheck(Range range, String binAgeRangeStr) { List<Long> segmentList = range.getSegmentList(); List<Long> inputSegmentList = createSegment(binAgeRangeStr); for (int i = 0; i < segmentList.size(); i++) { Long segmentBin = segmentList.get(i); Long inputSegmentBin = inputSegmentList.get(i); if ((segmentBin & inputSegmentBin) != segmentBin) { return false; } } return true; } static List<Long> createSegment(String binAgeRangeStr) { int length = binAgeRangeStr.length(); int segmentNum = length >> 6; List<Long> segmentList = new ArrayList<>(); int start = 0; for (int i = 0; i < segmentNum; i++) { int end = start + 64; addSegmentRadix2Long(binAgeRangeStr, segmentList, start + 1, end); start = end; } if (start < length) { addSegmentRadix2Long(binAgeRangeStr, segmentList, start, length); } return segmentList; } private static void addSegmentRadix2Long(String binAgeRangeStr, List<Long> segmentList, int start, int end) { String segmentStr = binAgeRangeStr.substring(start, end); segmentList.add(Long.parseLong(segmentStr, 2)); } /** * 不是數字,或者字串為空,則直接返回 * * @param binAgeRange * @throws RuntimeException */ static void checkBinAgeRange(String binAgeRange) { if (StringUtils.isBlank(binAgeRange) || !StringUtils.isNumeric(binAgeRange)) { throw new RuntimeException("輸入的二進位制字串不能為空,且格式為數字"); } } }

package test;

import java.util.List;

/**
 * Created by zzq on 2020/11/27.
 */
public abstract class Range {
    String typeId;//分類Id
    String rangeTag;//範圍記號
    private List<Long> segmentList;

    public List<Long> getSegmentList() {
        return segmentList;
    }

    public String getTypeId() {
        return typeId;
    }

    public void setTypeId(String typeId) {
        this.typeId = typeId;
    }

    public String getRangeTag() {
        return rangeTag;
    }

    public void setRangeTag(String rangeTag) {
        this.rangeTag = rangeTag;
    }

    abstract String getBinRangeStr();//需要設定binRangeStr二進位制字串

    void initSegmentList() {
        String binRangeStr = getBinRangeStr();
        RangeProcessor.checkBinAgeRange(binRangeStr);
        segmentList = RangeProcessor.createSegment(binRangeStr);
    }
}

package test;

import lombok.Data;

/**
 * Created by zzq on 2020/11/27.
 */
@Data
public class MediaAgeRange extends Range {
    int startAge;
    int endAge;

    @Override
    String getBinRangeStr() {
        char ageRange[] = new char[128];
        for (int i = 0; i < 128; i++) {
            if (i >= startAge && i <= endAge)
                ageRange[i] = 49;
            else
                ageRange[i] = 48;
        }
        return String.valueOf(ageRange);
    }
}

package test;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by zzq on 2020/11/27.
 */
public class Test {
    public static void main(String[] args) throws Exception {
        List<Range> mediaAgeRangeList = new ArrayList<>();
///*
        //18歲以下
        MediaAgeRange mediaAgeRange = new MediaAgeRange();
//        mediaAgeRange.setBinAgeRange("01111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
        mediaAgeRange.setStartAge(1);
        mediaAgeRange.setEndAge(17);
        mediaAgeRange.setRangeTag("1");
        mediaAgeRange.setTypeId("baidu");
        mediaAgeRangeList.add(mediaAgeRange);
        //18-24歲
        MediaAgeRange mediaAgeRange1 = new MediaAgeRange();
//        mediaAgeRange1.setBinAgeRange("00000000000000000011111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
        mediaAgeRange1.setStartAge(18);
        mediaAgeRange1.setEndAge(24);
        mediaAgeRange1.setRangeTag("2");
        mediaAgeRange1.setTypeId("baidu");
        mediaAgeRangeList.add(mediaAgeRange1);
        //25-34歲
        MediaAgeRange mediaAgeRange2 = new MediaAgeRange();
//        mediaAgeRange2.setBinAgeRange("00000000000000000000000001111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
        mediaAgeRange2.setStartAge(25);
        mediaAgeRange2.setEndAge(34);
        mediaAgeRange2.setRangeTag("3");
        mediaAgeRange2.setTypeId("baidu");
        mediaAgeRangeList.add(mediaAgeRange2);
        //35-44歲
        MediaAgeRange mediaAgeRange3 = new MediaAgeRange();
//        mediaAgeRange3.setBinAgeRange("00000000000000000000000000000000000111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000");
        mediaAgeRange3.setStartAge(35);
        mediaAgeRange3.setEndAge(44);
        mediaAgeRange3.setRangeTag("4");
        mediaAgeRange3.setTypeId("baidu");
        mediaAgeRangeList.add(mediaAgeRange3);
        //44歲以上
        MediaAgeRange mediaAgeRange4 = new MediaAgeRange();
//        mediaAgeRange4.setBinAgeRange("00000000000000000000000000000000000000000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
//        mediaAgeRange4.setBinAgeRange("00000000000000000000000000000000000000000000011111111111111111111111111111111111111111111111111111111111111111111111111111111111");
        mediaAgeRange4.setStartAge(45);
        mediaAgeRange4.setEndAge(127);
        mediaAgeRange4.setRangeTag("5");
        mediaAgeRange4.setTypeId("baidu");
        mediaAgeRangeList.add(mediaAgeRange4);

//*/
        RangeProcessor rangeProcessor = new RangeProcessor(mediaAgeRangeList);
        String abc = "00000000000000000011111111111111111000000000011111111111111111111111111111111111111111111111111111111111111111111111111111111111";
        String uu = "00000000000000111111111111111111111111111111111111111111111110000000000000000000000000000000000000000000000000000000000000000000";
        List<String> ret = rangeProcessor.getRangeTagList("baidu", abc);
        List<String> re1t = rangeProcessor.getRangeTagList("baidu", uu, true);


        System.out.println();
    }

}