简体   繁体   中英

JAVA: Lexicographically comparing two Strings

I am attending an IT school and we just started studying JAVA and we had to do a project that sort of simulated simple "messages" being passed around a network of Nodes that had IP Addresses.

The whole project does not matter for purposes of this question.

We have an IPAddress class, and one of its methods is to compare three IP address objects and decide whether the first one is "in the range" of the other two.

For example, let's have a Node in the system, call it N1 (there is a whole node class but that's unimportant atm) and have a package(also its own class) with the message "Hello" in it.

The package has the IP Address of 127.0.0.1

The system wants to pass it onto N1 which has an IP address of something (irrelevant) and an IP address range (which shows which range of IPs does it handle) of

127.0.0.0 (lower limit) and 127.0.0.255(upper limit)

The IPAddress class InsideRange method receives two IPs as parameters to compare it with the third in the following way:

public boolean insideRng(IPAddress lower, IPAddress upper){
    String this_str = this.toString();
    String lower_str = lower.toString();
    String upper_str = upper.toString();
    String[] addressses = {this_str, lower_str, upper_str}; 
    for (int i=0; i<addressses.length; i++){
        String[] tmp = addressses[i].split("\\."); 
        addressses[i] = String.format("%3s.%3s.%3s.%3s",tmp[0],tmp[1],tmp[2],tmp[3]); 
    }
    String address = addressses[0]; 
    Arrays.sort(addressses);
    return (addressses[1].equals(address));
} 

In this case 127.0.0.1 IS INSIDE 127.0.0.0 and 127.0.0.255 so it returns true.

I did not make the above code however, I asked a friend to help me. The reason is that my version did not properly work (it returns true for an IP that is outside of the lower or upper limit sometimes):

public boolean insideRng(IPAddress lower, IPAddress upper){ //nem mukodott
    String lower_str = lower.toString();
    String upper_str = upper.toString();
    String this_str = this.toString();
    return (lower_str.compareTo(this_str) <= 0 & upper_str.compareTo(this_str) >= 0);
} //(This is my version. THIS DOES NOT WORK)

My question is, why doesn't mine work? And:

WHAT does this part do and why is the for loop needed at all

for (int i=0; i<addressses.length; i++){
    String[] tmp = addressses[i].split("\\."); 
    addressses[i] = String.format("%3s.%3s.%3s.%3s",tmp[0],tmp[1],tmp[2],tmp[3]);
}

why doesn't it work if I just go:

public boolean insideRng(IPAddress lower, IPAddress upper){
    String this_str = this.toString();
    String lower_str = lower.toString();
    String upper_str = upper.toString();
    String[] addressses = {this_str, lower_str, upper_str};
    String address = addressses[0]; //address = "127.0.0.1";
    Arrays.sort(addressses);
    return (addressses[1].equals(address));
} 

(the toString() method does not call the original java toString method used on strings but instead IPadddress has an overridden toString() method which I will paste here:)

@Override
public String toString(){
    StringBuilder a = new StringBuilder();
    for(int i = 0; i < this.address.length -1; ++i){ 
        a.append(this.address[i]).append(".");
    }
    a.append(address[address.length-1]);
    return a.toString(); 
}

If I understand correctly, you are asking why comparing IP Strings such as these doesn't work :

"2.0.0.127" and "10.0.0.127"

The answer is that any String that starts with 2 comes (lexicographically) after a String that starts with 1.

The for loop you mentioned takes care of the problem by padding the numbers that make the IP String with leading zeroes :

So, when you are comparing these Strings:

"002.000.000.127" and "010.000.000.127"

You'll get the expected result (which is that 002 comes before 010).

EDIT :

As Dave correctly commented, the padding in the for loop is actually with SPACEs, not zeroes, so the compared Strings become :

"--2.---.---.127" and "-10.---.---.127"
Where '-' stands for SPACE.

Fortunately, this gives the same comparison result as padding with zeros would.

Eran answer is good, my opinion is that you are expecting to make your IPAdress class implementing Comparable

And define your compareTo method to take care of the different adresses in your adresses array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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