Search code examples
javabufferedreader

Translate words in a string using BufferedReader (Java)


I've been working on this for a few days now and I just can't make any headway. I've tried using Scanner and BufferedReader and had no luck.

Basically, I have a working method (shortenWord) that takes a String and shortens it according to a text file formatted like this:

hello,lo
any,ne
anyone,ne1
thanks,thx

It also accounts for punctuation so 'hello?' becomes 'lo?' etc.

I need to be able to read in a String and translate each word individually, so "hello? any anyone thanks!" will become "lo? ne ne1 thx!", basically using the method I already have on each word in the String. The code I have will translate the first word but then does nothing to the rest. I think it's something to do with how my BufferedReader is working.

import java.io.*;

public class Shortener {
    private FileReader in ;
    /*
     * Default constructor that will load a default abbreviations text file.
     */
    public Shortener() {
        try {
            in = new FileReader( "abbreviations.txt" );
        }       

        catch ( Exception e ) {
            System.out.println( e );
        }
    }

    public String shortenWord( String inWord ) {
        String punc = new String(",?.!;") ;
        char finalchar = inWord.charAt(inWord.length()-1) ;
        String outWord = new String() ;
        BufferedReader abrv = new BufferedReader(in) ;

            // ends in punctuation
            if (punc.indexOf(finalchar) != -1 ) {
                String sub = inWord.substring(0, inWord.length()-1) ;
                outWord = sub + finalchar ;


            try {
                String line;
                while ( (line = abrv.readLine()) != null ) {
                    String[] lineArray = line.split(",") ;
                        if ( line.contains(sub) ) {
                            outWord = lineArray[1] + finalchar ;
                            }
                        }
                    }

            catch (IOException e) {
                System.out.println(e) ;
                }
            }

            // no punctuation
            else {
                outWord = inWord ;

                try {
                String line;

                    while( (line = abrv.readLine()) != null) {
                        String[] lineArray = line.split(",") ;
                            if ( line.contains(inWord) ) {
                                outWord = lineArray[1] ;
                            }
                        }
                    }

                catch (IOException ioe) {
                   System.out.println(ioe) ; 
                }
            }

        return outWord;
    }

    public void shortenMessage( String inMessage ) {
         String[] messageArray = inMessage.split("\\s+") ;
         for (String word : messageArray) {
            System.out.println(shortenWord(word));
        }
    }
}

Any help, or even a nudge in the right direction would be so much appreciated.

Edit: I've tried closing the BufferedReader at the end of the shortenWord method and it just results in me getting an error on every word in the String after the first one saying that the BufferedReader is closed.


Solution

  • I think you can have a simpler solution using a HashMap. Read all the abbreviations into the map when the Shortener object is created, and just reference it once you have a word. The word will be the key and the abbreviation the value. Like this:

    public class Shortener {
    
        private FileReader in;
        //the map
        private HashMap<String, String> abbreviations;
    
        /*
         * Default constructor that will load a default abbreviations text file.
         */
        public Shortener() {
            //initialize the map
            this.abbreviations = new HashMap<>();
            try {
                in = new FileReader("abbreviations.txt" );
                BufferedReader abrv = new BufferedReader(in) ;
                String line;
                while ((line = abrv.readLine()) != null) {
                    String [] abv = line.split(",");
                    //If there is not two items in the file, the file is malformed
                    if (abv.length != 2) {
                        throw new IllegalArgumentException("Malformed abbreviation file");
                    }
                    //populate the map with the word as key and abbreviation as value
                    abbreviations.put(abv[0], abv[1]);
                }
            }       
    
            catch ( Exception e ) {
                System.out.println( e );
            }
        }
    
        public String shortenWord( String inWord ) {
            String punc = new String(",?.!;") ;
            char finalchar = inWord.charAt(inWord.length()-1) ;
    
            // ends in punctuation
            if (punc.indexOf(finalchar) != -1) {
                String sub = inWord.substring(0, inWord.length() - 1);
    
                //Reference map
                String abv = abbreviations.get(sub);
                if (abv == null)
                    return inWord;
                return new StringBuilder(abv).append(finalchar).toString();
            }
    
            // no punctuation
            else {
                //Reference map
                String abv = abbreviations.get(inWord);
                if (abv == null)
                    return inWord;
                return abv;
            }
        }
    
        public void shortenMessage( String inMessage ) {
             String[] messageArray = inMessage.split("\\s+") ;
             for (String word : messageArray) {
                System.out.println(shortenWord(word));
            }
        }
    
        public static void main (String [] args) {
            Shortener s = new Shortener();
            s.shortenMessage("hello? any anyone thanks!");
        }
    }
    

    Output:

    lo?
    ne
    ne1
    thx!
    

    Edit:

    From atommans answer, you can basically remove the shortenWord method, by modifying the shortenMessage method like this:

    public void shortenMessage(String inMessage) {
         for (Entry<String, String> entry:this.abbreviations.entrySet()) 
             inMessage = inMessage.replaceAll(entry.getKey(), entry.getValue());
    
         System.out.println(inMessage);
    }