Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 9 of 9

Thread: Oracle's answer to exercise 1 in Interfaces - Java Tutorials

  1. #1
    Junior Member
    Join Date
    Sep 2012
    Posts
    4
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Default Oracle's answer to exercise 1 in Interfaces - Java Tutorials

    Newbie in Java, I have two missing points from Exercise 1 here.
    Thanks in advance for any comments.

    1. After execution of the first 2 lines in main, what is the value of var charSequenceDemo s? NetBean IDE 7.1.2 shows it reversed in debugging mode, but could it be cause of the use of method toString() to show it? So, is the value of s:
    a. the original string, but when we come to "see" it, we are forced to reverse it or
    b. the string is reversed, which I don't understand why.

    2. method subSequence, if end = s.length() then fromEnd(end) = -1 and method subSequence is not exactly as the interface CharSequence describes. Of course main is protected in line
    int end = random(s.length() - 1 - start) + start;
    (with the -1), but shouldn't be better, to ommit -1 in methods fromEnd, main?

    // CharSequenceDemo presents a String value -- backwards.
    public class CharSequenceDemo implements CharSequence {
        private String s;
     
        public CharSequenceDemo(String s) {
            //It would be much more efficient to just reverse the string
            //in the constructor. But a lot less fun!
            this.s = s;
        }
     
        //If the string is backwards, the end is the beginning!
        private int fromEnd(int i) {
            return s.length() - 1 - i;
        }
     
        public char charAt(int i) {
            if ((i < 0) || (i >= s.length())) {
                throw new StringIndexOutOfBoundsException(i);
            }
            return s.charAt(fromEnd(i));
        }
     
        public int length() {
            return s.length();
        }
     
        public CharSequence subSequence(int start, int end) {
            if (start < 0) {
                throw new StringIndexOutOfBoundsException(start);
            }
            if (end > s.length()) {
                throw new StringIndexOutOfBoundsException(end);
            }
            if (start > end) {
                throw new StringIndexOutOfBoundsException(start - end);
            }
            StringBuilder sub = 
                new StringBuilder(s.subSequence(fromEnd(end), fromEnd(start)));
            return sub.reverse();
        }
     
        public String toString() {
            StringBuilder s = new StringBuilder(this.s);
            return s.reverse().toString();
        }
     
        //Random int from 0 to max.
        private static int random(int max) {
            return (int) Math.round(Math.random() * max + 0.5);
        }
     
        public static void main(String[] args) {
            CharSequenceDemo s =
                new CharSequenceDemo("Write a class that implements the CharSequence interface found in the java.lang package.");
     
            //exercise charAt() and length()
            for (int i = 0; i < s.length(); i++) {
                System.out.println(s.charAt(i));
            }
     
            //exercise subSequence() and length();
            int start = random(s.length() - 1);
            int end = random(s.length() - 1 - start) + start;
            System.out.println(s.subSequence(start, end));
     
            //exercise toString();
            System.out.println(s);
     
        }
    }
    Last edited by MaXER; September 19th, 2012 at 01:20 AM.


  2. #2
    Super Moderator helloworld922's Avatar
    Join Date
    Jun 2009
    Posts
    2,896
    Thanks
    23
    Thanked 619 Times in 561 Posts
    Blog Entries
    18

    Default Re: Oracle's answer to exercise 1 in Interfaces - Java Tutorials

    1. Strings are immutable (i.e. a String object can't be changed/modified). The only way to modify a String is to change what String object a String variable refers to.

    2. If you want to add extra checks to fromEnd() you can. Regardless you should do your best to ensure that invalid values don't get passed to fromEnd() since technically you are "-1" away from the end (i.e. the index is 1 index in the opposite direction you assumed), but this index doesn't hold valid data.

  3. #3
    Junior Member
    Join Date
    Sep 2012
    Posts
    4
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Default Re: Oracle's answer to exercise 1 in Interfaces - Java Tutorials

    Thank you.

    Trying to apply your comment to my question, I'm now confused: charSequenceDemo var s refers to a charSequenceDemo Odject, not a String Object. How IDE shows its value as a string? Should I guess that as class charSequenceDemo implements CharSequence interface, IDE applies toString method?
    Quote Originally Posted by helloworld922 View Post
    1. Strings are immutable (i.e. a String object can't be changed/modified). The only way to modify a String is to change what String object a String variable refers to.
    Please let me place an argument: the real end in strings is index s.length(), I think it holds the string's end marker, not of any value char but a valid index. What we need is a starting valid, relative point of start(0, which there is no need to be reversed) to express the same positions in reverse "view" and this is accomplished better I think with this position, mostly because of method subSequence.
    2. If you want to add extra checks to fromEnd() you can. Regardless you should do your best to ensure that invalid values don't get passed to fromEnd() since technically you are "-1" away from the end (i.e. the index is 1 index in the opposite direction you assumed), but this index doesn't hold valid data.

  4. #4
    Super Moderator helloworld922's Avatar
    Join Date
    Jun 2009
    Posts
    2,896
    Thanks
    23
    Thanked 619 Times in 561 Posts
    Blog Entries
    18

    Default Re: Oracle's answer to exercise 1 in Interfaces - Java Tutorials

    Trying to apply your comment to my question, I'm now confused: charSequenceDemo var s refers to a charSequenceDemo Odject, not a String Object. How IDE shows its value as a string? Should I guess that as class charSequenceDemo implements CharSequence interface, IDE applies toString method?
    Oh, I see. The variable name s is used in so many different places it's confusing to keep them straight What I was referring to was the String field s inside the CharSequenceDemo class.

    The IDE (and indeed many places in Java) automatically call the toString() method to get a string representation of an object. You can examine the fields inside of the CharSequenceDemo object s in the debugger and verify what the value of the string field s is.

    Please let me place an argument: the real end in strings is index s.length(), I think it holds the string's end marker, not of any value char but a valid index. What we need is a starting valid, relative point of start(0, which there is no need to be reversed) to express the same positions in reverse "view" and this is accomplished better I think with this position, mostly because of method subSequence.
    Most likely yes, the data at s[s.length()] is the null terminator, '\0'. However, we ignore this because it's not really part of the string. It's there to tell us where the string ends. The last valid index of string data is at s[s.length() - 1]. I've dealt with some code (extremely rare) which uses a different mechanism for determining when strings end, and that's by using a length field before the start of the string data. Here there's no null terminator so trying to access s[s.length()] will return data which is complete garbage.

    Ex.:

    Consider the string "hello world". This could be stored in data like this:

    ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '\0']

    When you reverse the string, you would end up with this:

    ['d', 'l', 'r', 'o', 'w', ' ', 'o', 'l', 'l', 'e', 'h', '\0']

    We need to keep the null terminator at the end so the computer knows when the string ends. It doesn't make any sense to do this:

    ['\0', 'd', 'l', 'r', 'o', 'w', ' ', 'o', 'l', 'l', 'e', 'h']

  5. #5
    Junior Member
    Join Date
    Sep 2012
    Posts
    4
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Default Re: Oracle's answer to exercise 1 in Interfaces - Java Tutorials

    1. It's a relief to know this , as I can understand it. So the given answer to Ex.1 really reverses a string, not in the constructor, but through methods (the fun way as writer comments).

    2. I've used your example:
    /*
    ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '\0']	original string
    ['d', 'l', 'r', 'o', 'w', ' ', 'o', 'l', 'l', 'e', 'h', '\0']	reversed string
      0    1    2    3    4    5    6    7    8    9    10   11	positions
    */
    Let me show you how far I went and if you want you could comment.
    Starting from method charAt(i), it returns the char of the reversed string at position i, as the char of the original string at (s.length() - 1 - i). Here I think comes the need of a function to relate position in reversed string with the relative position in original string, to be used in both charAt() and subSequence() methods. This is fromEnd -I would prefer to name it int posInOriginal(int posInReversed).
    Next is method subSequence(int start, int end). It returns CharSequence that derives from reversed string from position start inclusive, to position end exclusive, as the reverse of subSequence of original string that starts from the related position of (end-1), that is fromEnd(end-1), to (the related position of start) + 1, that is fromEnd(start)+1.
    Notice the difference with Oracle's answer and that now when end = s.length(), positions end-1, fromEnd(end-1) are valid at reversed and original string accordingly.
    Also when start = 0, position fromEnd(start)+1=s.length() is valid as a second parameter in subSequence method.
    Last edited by MaXER; September 23rd, 2012 at 06:33 AM.

  6. #6
    Member
    Join Date
    Jun 2012
    Location
    Left Coast, USA
    Posts
    451
    My Mood
    Mellow
    Thanks
    1
    Thanked 97 Times in 88 Posts

    Default Re: Oracle's answer to exercise 1 in Interfaces - Java Tutorials

    I hate to butt in, but sometimes I just can't help myself.

    Regardless of the example with reversing Java Strings, the discussion regarding terminating zero bytes would be appropriate for a discussion of the C language (in which there is no string data type), but not for Java. The author and maintainers of the C language have implemented various library functions dealing with char pointers and char arrays, and have defined string literals that are convenient for lots of things related to "strings" in C. Key to all of the standard (useful) ways of dealing with "strings" in C is the treatment of the terminating zero byte in the char sequence. Since there is no string data type in C, C programmers who want to have "string-like" things in their programs have to know this kind stuff, right?

    However...

    I believe that is completely irrelevant in discussion of Java Strings. It is possible to create a Java String object with a zero character in the middle of the String. (By "zero character" I mean a character whose binary value is Unicode zero.)

    I don't know or care how Java Strings are represented internally, and even if there happened to be an implicit zero character (or other terminating character with some particular value) at the end of the String, it would not be accessible from a "normal" user application program String function, since an attempt to read the character at the String's length() position results in a run-time error. (That's why I used the word irrelevant in the context of Java.)

    Java Example:
    // Demo of a String with a zero in the middle
    //
    // Zaphod_b
    //
    public class Z {
     
        public static void main(String [] args) {
            // \u0000 indicates a unicode character 0 in the
            // middle of the string literal.
            String str = "Write a \u0000 class.";
            System.out.printf("str: <%s>\n", str);
            for (int i = 0; i < str.length(); i++) {
                System.out.printf("%2d: 0x%04x\n", i, (int)str.charAt(i));
            }
        }
    }

    Output (Java 1.6)
    str: <Write a  class.>
     0: 0x0057
     1: 0x0072
     2: 0x0069
     3: 0x0074
     4: 0x0065
     5: 0x0020
     6: 0x0061
     7: 0x0020
     8: 0x0000
     9: 0x0020
    10: 0x0063
    11: 0x006c
    12: 0x0061
    13: 0x0073
    14: 0x0073
    15: 0x002e


    The value at position 8 of the String is zero. A character with that particular value does not show up in the print of the String (look carefully: there are exactly two space characters between "Write a" and "class" in the printout), but you can see it when you address the individual characters. If you redirect output of this little program to a file, you can verify that there is a zero byte at position 8 of the String in the file. My main point is that the String is not terminated by a char whose value is zero.

    Note that I used zero for my example because that's what the previous discussion was about.
    If you still think there is some magical implicit terminating character for Java Strings, try this:

    Put any UTF16 character you want in the middle of a Java String. The String will not be terminated by that character. At least that's what I have tested with Java 6. I welcome further edification.


    In C programs, if you define a string literal with a zero in the middle, the C-style "string" that results is terminated at that point. (So the print of a "string" from that kind of string literal with a "<%s>" format specifier shows <Write a >. I won't bother Java forum readers with C code.)

    Note that in C++, string literals are defined as they were in C, so a zero byte in the middle of the string literal results in a C-style "string" that is terminated at that point. But (and this is important for programs reading bytes into a C++ std::string object from a binary file or from a network stream) it is possible to have a zero byte in the middle of a C++ std::string object. (I won't bother Java forum readers with C++ code.)

    Bottom line: I would keep the C-style stuff in a separate compartment in my long-term memory and concentrate on Java Strings instead of making incorrect analogies. In particular: Java "knows" where the end of the String is, and "normal" Java user programs have access to that information by using the String length() method. Period.


    Cheers!

    Z
    Last edited by Zaphod_b; September 23rd, 2012 at 01:02 PM.

  7. The Following 2 Users Say Thank You to Zaphod_b For This Useful Post:

    helloworld922 (September 23rd, 2012), MaXER (September 24th, 2012)

  8. #7
    Super Moderator helloworld922's Avatar
    Join Date
    Jun 2009
    Posts
    2,896
    Thanks
    23
    Thanked 619 Times in 561 Posts
    Blog Entries
    18

    Default Re: Oracle's answer to exercise 1 in Interfaces - Java Tutorials

    Sounds reasonable to me, so most likely Java uses the other mechanism I described where string length is stored somewhere (which makes sense since there's a constant length field ). However, as Zaphod_b pointed out it's not really useful to think about the termination style in Java which is one of the reasons I kind of poorly assumed it was similar to how C did things. Regardless of termination/keeping track method, index s.get(s.length) doesn't hold valid data pertaining to the string char sequence.

    This is fromEnd - i would prefer to name it int posInOriginal(int posInReversed).
    Yep, this is a very good alternative name for the method. It really has to deal with the fact that Java (and C/C++ for that matter) starts counting indices from 0 instead of from 1.

  9. The Following User Says Thank You to helloworld922 For This Useful Post:

    MaXER (September 24th, 2012)

  10. #8
    Junior Member
    Join Date
    Sep 2012
    Posts
    4
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Default Re: Oracle's answer to exercise 1 in Interfaces - Java Tutorials

    Quote Originally Posted by Zaphod_b View Post
    I hate to butt in, but sometimes I just can't help myself.
    Not for a good reason, as to clarify something, I think, which I'm grateful for.

    @helloword922, Zaphod_b
    So if in Java the char reference at s.length() position is a NO, why to have parameters like end in subSequence(int start, int end) even as excluded that prone to errors and not as int end included (end < s.length())? Should I guess that Java's past and relation with C, is not something that can change so easily?
    Last edited by MaXER; September 24th, 2012 at 01:07 AM.

  11. #9
    Super Moderator helloworld922's Avatar
    Join Date
    Jun 2009
    Posts
    2,896
    Thanks
    23
    Thanked 619 Times in 561 Posts
    Blog Entries
    18

    Default Re: Oracle's answer to exercise 1 in Interfaces - Java Tutorials

    It's possible it's done in C and other languages for completeness. It's possible for subSequence to return an empty CharSequence (start = end). If you implemented subSequence to include the index end, then I one way to get an empty result would be to have start = end + 1. In Java this would work perfectly fine most of the time since the only unsigned type is char (i.e. non-negative), and it's use as an unsigned number is unorthodox (basically, don't try to do this without a very good reason).

    However, if you did happen to use char's in this manner (or use another language which supports true unsigned data types), then you run into an issue mathematically when start = 0, because that would require end=-1 which isn't possible with unsigned types.

    It could be argued here that calling subSequence in this unique manner to get an empty sequence is not very useful, but it is still possible and computer scientists dislike incompleteness.

    In Java's case it's most likely it's done just to make porting code easier, or is done purely out of habit. I know I personally pretty much always implement methods which deal with sequences to include the first index and exclude the last one out of habit.

    There could also be other reasons early programming languages did this pertaining to some obscure optimization which made significant differences back then, but now this either is insignificant or is done by the compiler for you anyways.

    What-ever the reason, it's there so you might as well live with it (unless you want to go about creating your own language/libraries)

Similar Threads

  1. Java Programming Exercise
    By Garron5899 in forum Loops & Control Statements
    Replies: 5
    Last Post: July 27th, 2012, 08:12 AM
  2. Java Tutorials and Help
    By theitranger in forum The Cafe
    Replies: 4
    Last Post: March 31st, 2011, 05:24 PM
  3. Basic Java Tutorials
    By uimbibe in forum The Cafe
    Replies: 0
    Last Post: January 26th, 2011, 12:55 PM
  4. Java: interfaces and abstract classes
    By pinansonoyon in forum Object Oriented Programming
    Replies: 1
    Last Post: May 6th, 2010, 10:17 AM
  5. JAVA exercise
    By gmilan in forum What's Wrong With My Code?
    Replies: 0
    Last Post: March 13th, 2010, 02:30 PM