Skip to content

How do I break up words in a String ArrayList in Java and then reverse them?

The title may sound confusing.

Simply, I have a file that have text inside of it. I used a scanner to read that text. I stored that text into an ArrayLists that is a String. The problem I have is that I need to make a method reverses the text in that ArrayList. The text does reverse, but not completely. I need the words to be in reverse order too, but my String ArrayList is broken down in sentences.

Therefore, I need help reaching in each ArrayList and breaking those words up into other ” ” and then put them in my method so it can reverse the words properly.

What I want to be accomplished is first breaking apart the lines and reverse the words. The difficult part is still returning the whole text in lines. My professor recommended creating helper methods to solve this. Please help.

 package thePackage;
   /**
    * Adan Vivero
   * 12.6.18
   * In this lab, I will be working with classes, 
   ArrayLists, and files 
   * mainly.
   */

 import java.io.File;
 import java.util.ArrayList;
 import java.io.*;
 import java.util.*;

 /**
 * In this class, we create two private variables which is a File and 
 * ArrayList that is a String that will be
 * initialized later on in the code.
 */
 public class FileManipulator
 {
 private File inputFile;
 private ArrayList <String> words;
 /**
 * In this method, we are initializing the File and Arraylist and 
 * having a Scanner reach a file to grab the text
 * and insert it into the ArrayList as a String.
 * @param fileName is a type String that the user in the other class 
 * "FileDriver" types in and it reads the file.
 * @throws FileNotFoundException if the file does not exist.
 */
 public FileManipulator(String fileName) throws FileNotFoundException
 {
    inputFile = new File(fileName);
    words = new ArrayList<String>();
    Scanner fileWords = new Scanner(inputFile);
    while(fileWords.hasNextLine())  /** This will read the file and 
 continue to loop as long as there are still more lines left to read 
 from the file. */
    {
        String lineScan = fileWords.nextLine(); /** I created a String 
 called LineScan that will read the whole line of the file as a String 
 */
        words.add(lineScan);    /** Right here, we add whatever the 
 String LineScan read, into the String ArrayList. (It adds in lines, 
 not individual words.) */
    }
    System.out.println(words.size() + " ");
 }

/**
 * In this method, the goal is to reverse everything that is in the 
ArrayList "words". It is flawed at the moment since
 * it correctly returns the lines in reverse order, but the words in 
each line are not reversed. 
 */
public void reverse()
{
    for(int i = words.size()-1; i >= 0; i--) /** This for loop reverses 
*each of the lines in reverse order. */
    {
        System.out.println(words.get(i) + " ");
    }
    for(int i = 0; i < words.size(); i++)
    {
        //System.out.print(words.get(i) + " ");
    }
 }
 public void removePlurals()
 {
    for(int i = words.size()-1; i >= 0; i--)
    {
        String plurals = words.get(i);
        if(plurals.endsWith("s"))
        {
            words.remove(i);
        }
        System.out.println(words.get(i) + " ");
    }
 }
 public void stutter(int k)
 {
    k = 3;
    for(int i = words.size()-1; i <= words.size()-1; i++)
    {
        System.out.println(words.get(i));
    }
}
}

The current output:

when tweetle beetles fight , 
it's called a tweetle beetle battle .

and when they battle in puddles , 
they are tweetle beetle puddle battles .

and when tweetle beetles battle with paddles in puddles , 
they call them tweetle beetle puddle paddle battles .

and ...

when beetles battle beetles in  puddle paddle battles 
and the beetle battle puddles are puddles in  bottles ...
... they call these tweetle beetle bottle puddle paddle battle muddles .

and ...

when beetles fight these bottle battles with their paddles 
and the bottles are on poodles and the poodles are eating noodles ...
... they call these muddle puddle tweetle poodle beetle noodle 
bottle paddle battles .

The Desired Output:

. battles paddle bottle
noodle beetle poodle tweetle puddle muddle these call they ...
... noodles eating are poodles the and poodles on are bottles the and
paddles their with battles bottle these fight beetles when

... and

. muddles battle paddle puddle bottle beetle tweetle these call they ...
... bottles in puddles are puddles battle beetle the and
battles paddle puddle in beetles battle beetles when

... and

. battles paddle puddle beetle tweetle them call they
, puddles in paddles with battle beetles tweetle when and

. battles puddle beetle tweetle are they
, puddles in battle they when and

. battle beetle tweetle a called it's
, fight beetles tweetle when

Answer

If you want to retain the sentences, but have the words in each sentence reversed you could do:

while(fileWords.hasNextLine()) {
    StringBuilder sb = new StringBuilder();
    String[] wordsArr = fileWords.nextLine().split("\s+");
    for(String str: wordsArr) {
        sb.insert(0, str).insert(str.length(), " ");
    }
    words.add(sb.toString());

}
Collections.reverse(words);
words.forEach(System.out::println);

If you are trying to obtain a List of the words in reverse order:

The problem is that you are adding lines to your List, and then printing those lines in reverse, but not the words. You can easily fix this by splitting the line on white space and adding all of those tokens to the List. You can do so using the split() method:

for(String str : lineScan.split("\s+")) {
    words.add(str);
}

However we can do this more elegantly with Collections.addAll:

Collections.addAll(words, lineScan.split("\s+")); 

Or when you’re printing you can split it into words there:

for(int i = words.size()-1; i >= 0; i--) 
{
    String[] wordArr = words.get(i).split("\s+");
    for(int j = wordArr.length - 1; j >= 0; j--) {
       System.out.println(wordArr[j]);
    }
}

Or java 8+:

BufferedReader br = new BufferedReader(new FileReader(fileName));
List<String> list = br.lines()
                      .map(e -> e.split("\s+"))
                      .flatMap(lineArr -> Arrays.stream(lineArr))
                      .collect(Collectors.toList());
Collections.reverse(list);

Which will use the lines() method to take a stream of the lines, split them into words, reverse them, and then collect them to a List, and then reverse them