繁体   English   中英

如何显示以特定数字开头的所有值

[英]How to show all the values that start with a specific number

我正在创建一个搜索以从100到600过滤一些Integer值。这些值是Http Status Codes ,因此我只想过滤它们。
搜索的工作方式如下:

  1. 用户输入一个搜索值,例如2并单击搜索
  2. 结果将是从200到299的所有值(因此所有值均以2开头)。
  3. 用户输入一个值,例如20,然后单击搜索
  4. 结果将是从200到209的所有值(因此所有以20开头的值)。
  5. 用户输入一个值,例如52,然后单击搜索
  6. 结果将是从520到529的所有值(因此所有以52开头的值)

我写了一些非常多余的代码,但是基本上解释了它应该如何工作:

     public void getHttpStatus(Integer httpStatus){
            if(httpStatus.equals(1)){
                messageRepository.findByHttpStatusBetween(100, 199);
            }
            else if(httpStatus.equals(2)){
                messageRepository.findByHttpStatusBetween(200, 299);
            }
            else if(httpStatus.equals(3)){
                messageRepository.findByHttpStatusBetween(300, 399);
            }
            else if(httpStatus.equals(4)){
                messageRepository.findByHttpStatusBetween(400, 499);
            }
            else if(httpStatus.equals(5)){
                messageRepository.findByHttpStatusBetween(500, 599);
            }
            else if(httpStatus.equals(10)){
                messageRepository.findByHttpStatusBetween(100, 109);
            }
            else if(httpStatus.equals(20)){
                messageRepository.findByHttpStatusBetween(200, 209);
            }
            else if(httpStatus.equals(30)){
                messageRepository.findByHttpStatusBetween(300, 309);
            }
            else if(httpStatus.equals(40)){
                messageRepository.findByHttpStatusBetween(400, 409);
            }
            else if(httpStatus.equals(50)){
                messageRepository.findByHttpStatusBetween(500, 509);
            }
            else if(httpStatus.equals(21)){
                messageRepository.findByHttpStatusBetween(210, 219);
            }
            ...
        }

有没有更简单的方法可以做到这一点? 还是有任何自动执行此操作的内置spring方法?

我将不胜感激任何建议。

假设您有一个包含所有状态代码的列表,则可以使用流过滤器,即

List<Integer> httpCodes;
String prefix = "5"
List<Integer> filteredResults = httpCodes.stream().filter(value -> value.toString().startsWith(prefix)).collect(Collectors.toList());

将代码存储为字符串,编写一个自定义查询,查找“ LIKE '50%'”等条目(LIKE'$ 1%')。

这里还有其他替代方法可以解决这个略有不同的问题: 检查整数的SQL LIKE条件?

我可能会这样:

public void getHttpStatus(Integer httpStatus){
 int numberOfDigits = (int) (Math.log10(number) + 1);
 int minStatus = httpStatus * ((int) Math.pow(10, 3 - numberOfDigits));
 int maxStatus = (httpStatus + 1) * ((int) Math.pow(10, 3 - numberOfDigits)) - 1
 messageRepository.findByHttpStatusBetween(minStatus,maxStatus)

}

或者你可以这样做

String status=  httpStatus.toString();
String startIndex = status;
String endIndex = status;

if ( status.length() == 1 )
{
    startIndex = status + "00";
    endIndex = status + "99";
}
else if ( status.length() == 2 )
{
    startIndex = status + "0";
    endIndex = status + "9";
}
int sIndex = Integer.parseInt( startIndex );
int eIndex = Integer.parseInt( endIndex );

messageRepository.findByHttpStatusBetween(sIndex, eIndex);

如果值是整数(或与一般操作兼容),则始终可以使用模( % )进行过滤。即:

void getStatus(httpCode){
    for(int i : codeList){
        if(i%httpCode >= 1) print i;
     }
}

对伪代码表示歉意,希望它能对您有所帮助。

编辑:我意识到有一个上限的需要,所以这可能不是理想的。 您仍然可以以这种方式实现它,只是要注意那可能是一个很大的痛苦。

public class Range {
    public int lb;
    public int ub;

    public Range(int lb, int ub) {
        this.lb = lb;
        this.ub = ub;
    }

    public Range(int statusCode) {
        int length = (int) (Math.log10(statusCode) + 1);
        if (length == 0 || length > 2) {
            throw new RuntimeException("Cant parse status code of invald length: " + length);
        }
        if (length == 1) {
            this.lb = statusCode * 100;
            this.ub = ((statusCode + 1) * 100) - 1;
        } else {
            this.lb = statusCode * 10;
            this.ub = ((statusCode + 1) * 10) - 1;
        }
    }
}


public class Main {
    public static void main(String[] args) {
        Range r1 = new Range(52);
        Range r2 = new Range(2);
        Range r3 = new Range(20);
        System.out.println("Lowerbound: " + r1.lb);
        System.out.println("Upperbound: " + r1.ub);
        System.out.println("Lowerbound: " + r2.lb);
        System.out.println("Upperbound: " + r2.ub);
        System.out.println("Lowerbound: " + r3.lb);
        System.out.println("Upperbound: " + r3.ub);
    }
}

输出如下:

Lowerbound: 520
Upperbound: 529
Lowerbound: 200
Upperbound: 299
Lowerbound: 200
Upperbound: 209

不检查特殊值0。

然后,您的函数可以重构为:

public void getHttpStatus(Integer httpStatus){
        Range r = new Range(httpStatus.intValue());
        messageRepository.findByHttpStatusBetween(r.lb, r.ub);
}

解决您的问题的一种方法是构建一个trie并使用用户输入中的数字作为关键字在其中进行搜索:

https://zh.wikipedia.org/wiki/特里

另一种解决方案是构建哈希表,并插入所有可能的前缀及其范围。 (例如,由于用户输入21是代码210、211、212、213、214、215、216、217、218、219的前缀,因此我们将(21、210、219)添加到表中,其中21是键,下限210,上限219。所有其他可能的用户输入也是如此。)

最多有500个三位数代码,这意味着该表最多包含1500个条目。

由于所有键和范围都是预先知道的并且是常量,因此您甚至可以使用完美的哈希并能够在恒定时间内找到范围。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM