[英]How to show all the values that start with a specific number
我正在创建一个搜索以从100到600过滤一些Integer值。这些值是Http Status Codes ,因此我只想过滤它们。
搜索的工作方式如下:
我写了一些非常多余的代码,但是基本上解释了它应该如何工作:
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.