Read each existing Line in Stringbuffer or String

Asked

Viewed 1,859 times

2

I have a text with the following format:

Data            Valor
20140901        278
20140902        248
20140903        458
20141004        545
20141005        125
20141106        1020
20141207        249

It is stored in an object of the type StringBuffer and would like to read line by line, someone has some idea of how to do?

Note: If there is a way to do likewise with a String will also be valid.

What I already have:

At the moment, I do not have a proper implementation, but the idea I have is to make a split (in this case, converting the StringBuffer for String) and pass as argument the character \n. But this idea is "performance", because I intend to process lines in the order of thousands.

1 answer

2


I have two suggestions, but to say which one will have the best performance just by testing...

Note: before starting, I suggest using a StringBuilder instead of a StringBuffer - the first is not thread-safe, so that its performance in a use single-threaded certainly will be better than the second. Your API is pretty much the same, so your code won’t need to be significantly changed.

  1. Using StringTokenizer (assuming that texto is a String):

    StringTokenizer st = new StringTokenizer(texto, "\n");
    while ( st.hasMoreTokens() ) {
        String linha = st.nextToken();
        ...
    }
    

    The original text will be kept intact (unlike a texto.split("\n"), for example, that would double the amount of memory used), and only small strings would be created - one per line - so that in total double the original memory would be used.

  2. Using CharBuffer. Unfortunately my knowledge of nio is quite limited, I don’t know if I can give a good example. But the potential of the CharBuffer about the StringTokenizer is that it would not be necessary to create a new String for each line of text - one could simply adjust the position (position) and the limit (limit) buffer to designate the "current line", and use the buffer itself as CharSequence (i.e. as if he were a String).

    The example below worked on the ideone, just do not guarantee - as I said - that is a good way to implement (assuming that texto is any CharSequence, including String, StringBuffer and StringBuilder):

    CharBuffer buffer = CharBuffer.wrap(texto);
    int inicio = 0, fim = 0;
    while ( fim < buffer.capacity() ) {
        if ( buffer.get(fim) == '\n' ) {
            buffer.position(inicio).limit(fim);
            // Usa-se buffer como se fosse uma String (i.e. a "próxima linha")
            ...
            buffer.position(0).limit(buffer.capacity());
            inicio = fim+1;
        }
        fim++;
    }
    

    If I’m not mistaken, the wrap initial creates a copy of the entire text, but once done the same can be discarded and no additional object creation operation will be performed. Or better yet, make sure texto already begin being a CharBuffer - for example reading it from the input file directly in that format.

reiterating, although method 2 seem better, in practice the creation and continuous destruction of objects String should not have too negative an impact on performance - since modern Vms use an efficient waste collector in this regard. In addition, other copies can be made inadvertently, nullifying the benefit. That is, to know which is the "best", just testing...

  • Thanks @mgibsonbr, it seems I don’t have another (a) alternative.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.