简体   繁体   中英

Why do I get a type mismatch when trying to reverse a string in Java?

So, I was always a novice programmer but recently decided to learn Java. I was just messing around with a small constructor that was to take in a string and then write it backwards (my method of doing this was in no way supposed to be efficient, I was simply using different tools available to me in order to become accustomed.) My error came when I was trying to add a char in an array to a string. This is the code:

public class dids {

    char letters[];

    public dids(String thing)
    {
        letters= new char[thing.length()];  
        for(char x:letters){
            letters[x] = thing.charAt(x);
        }
        for(int i=thing.length();i>0;i--){
            String retval += letters[i];
        }
    }
}

The error is saying I cannot add a char to a string. A type mismatch.

public class dids { //classes start with an upper case letter (Dids not dids)

char letters[];

public dids(String thing)
{

letters= new char[thing.length()];  //No null check can throw NPE
for(char x:letters){ //letters is an empty array.  
    letters[x] = thing.charAt(x);  
}
for(int i=thing.length();i>0;i--){//style is to count up
    String retval += letters[i]; //retval is recreated every time

}

}

}   

you want to use String.toCharArray to populate your array like so:

letters = thing.toCharArray();

The below code reverse a String.

StringBuilder sb = new StringBuilder(thing);  
sb = sb.reverse();  
String retval = sb.toString();

You haven't told us what the error is.

I spot the following:

  1. for(char x:letters){
    This form of the for loop will iterate over each character in letters . Thus, x will be set to each character in letters . However, you're attempting to use it as an index - which is kind-of ok since a char can be cast to an int . But, since you never initialize the array of characters ( letters ), you'll always get a value of 0 for x . Which means you're always setting the first element of letters , overwriting the previous.

  2. for(int i=thing.length()... .
    Since arrays are 0-indexed, the length will always be one more than the index of the last element. Thus, by accessing the array with the length of the array, you're going out of bounds by 1. You should initialize i to thing.length()-1 .

  3. String retval += letters[i];
    This fails to compile - you can't declare and append. retval should be declared outside of the for loop.


Here's a fix to your code that makes use of the toCharArray() method available for String objects:

public dids(String thing)
{
    letters= thing.toCharArray();

    String retval = "";
    for(int i=thing.length()-1;i>=0;i--){
         retval += letters[i];
    }

}

A slightly more efficient solution might be:

public dids(String thing)
{
    StringBuilder sb = new StringBuilder();
    for(int i = thing.length()-1; i >=0; i-- )
    {
        sb.append(thing.charAt(i));
    }
}

This is better because

a. String s are immutable which means that once created they cannot be modified (unless you resort to using reflection) and each time you append to a string, you're actually creating a new object which is wasteful in this situation. A StringBuilder or StringBuffer is meant to be used in a case where you want to make changes to a sequence of characters.

b. Since a String can be accessed character by character, you don't actually need to create a character array representation of the string to reverse it.

you need to declare retval outside the for loop:

public dids(String thing)
{

letters= new char[thing.length()];  
for(int x=0;x<letters.length;x++){//using index instead of char
    letters[x] = thing.charAt(x);
}
String retval=""
for(int i=thing.length()-1;i>=0;i--){//fixing of by one
     retval+= letters[i];

}

}

otherwise it is recreated and thrown away each time the loop runs

there were some other errors I fixed

There were multiple errors in your example. I've fixed the code and make it better working. The main error was, that you have declared the retval variable in the for loop.

public void dids(String thing) {
    System.out.println(thing);
    char letters[];


    letters =  thing.toCharArray();
    String retval = "";
    for (int i = thing.length()-1; i >= 0; i--) {
        retval = retval + letters[i];

    }
    System.out.println(retval);

}

In Java I'd do it more like this (note this is still very nasty, really I'd just something from the commons library, but you get the idea

public class Dids {

    private String _thing;  

    private String _reversed = "";

    public Dids(String thing) {             
        _thing = thing;             
    }

    public void reverse() {         
        for(int i=_thing.length()-1 ;i>-1; i--){
            _reversed += _thing.charAt(i);
        }
    }

    public String getReversed() {
        return _reversed;
    }
}

public class ReverseTester {

    public static void main(String[] args) {    
        String test = "abcd";

        Dids dids = new Dids(test);
        dids.reverse();

        System.out.println(dids.getReversed());
    }
}

This is kinda confusing but there are two errors in both for loops .

In the first you use the x as an index. x as you defined with char x is a char and not an int (well, maybe you might want to take a look at primitives conversion since this can be tricky). In the first loop at each iteration x will be updated and containg the 'next' char in the letters[] .

In the second loop at the very first iteration there will be an `IndexOutOfBoundException'. The last element of an array is equal to it's length-1 since arrays 0 based!

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