Grouping of words from a text file to Arraylist on the basis of length

大城市里の小女人 提交于 2019-12-25 07:58:35

问题


public class JavaApplication13 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
         BufferedReader br;
        String strLine;
        ArrayList<String> arr =new ArrayList<>();
        HashMap<Integer,ArrayList<String>> hm = new HashMap<>();
        try {
            br = new BufferedReader( new FileReader("words.txt"));
            while( (strLine = br.readLine()) != null){
                arr.add(strLine);
            }
        } catch (FileNotFoundException e) {
            System.err.println("Unable to find the file: fileName");
        } catch (IOException e) {
            System.err.println("Unable to read the file: fileName");
        }


        ArrayList<Integer> lengths = new ArrayList<>(); //List to keep lengths information 


        System.out.println("Total Words: "+arr.size()); //Total waords read from file

        int i=0;
        while(i<arr.size()) //this loop will itrate our all the words of text file that are now stored in words.txt
        {
            boolean already=false;
            String s = arr.get(i);
            //following for loop will check if that length is already in lengths list.
            for(int x=0;x<lengths.size();x++)
            {
                if(s.length()==lengths.get(x))
                    already=true;
            }
           //already = true means file is that we have an arrayist of the current string length in our map
            if(already==true)
            {

                hm.get(s.length()).add(s); //adding that string according to its length in hm(hashmap)
            }
            else
            {
                    hm.put(s.length(),new ArrayList<>()); //create a new element in hm and the adding the new length string
                    hm.get(s.length()).add(s);
                    lengths.add(s.length());

            }

            i++;
        }
        //Now Print the whole map
        for(int q=0;q<hm.size();q++)
        {
            System.out.println(hm.get(q));
        }
    }

}

is this approach is right?

Explanation:

  1. load all the words to an ArrayList.
  2. then iterate through each index and check the length of word add it to an ArrayList of strings containing that length where these ArrayList are mapped in a hashmap with length of words it is containing.

回答1:


Firstly, your code is working only for the files which contain one word by line as you're processing whole lines as words. To make your code more universal you have to process each line by splitting it to words:

String[] words = strLine.split("\\s+")

Secondly, you don't need any temporary data structures. You can add your words to the map right after you read the line from file. arr and lengths lists are actually useless here as they do not contain any logic except temporary storing. You're using lengths list just to store the lengths which has already been added to the hm map. The same can be reached by invoking hm.containsKey(s.length()).

And an additional comment on your code:

    for(int x=0;x<lengths.size();x++) {
        if(s.length()==lengths.get(x))
            already=true;
    }

when you have a loop like this when you only need to find if some condition is true for any element you don't need to proceed looping when the condition is already found. You should use a break keyword inside your if statement to terminate the loop block, e.g.

    for(int x=0;x<lengths.size();x++) {
        if(s.length()==lengths.get(x))
            already=true;
            break; // this will terminate the loop after setting the flag to true
    }

But as I already mentioned you don't need it at all. That is just for educational purposes.




回答2:


Your approach is long, confusing, hard to debug and from what I see it's not good performance-wise (check out the contains method). Check this:

String[] words = {"a", "ab", "ad", "abc", "af", "b", "dsadsa", "c", "ghh", "po"};
Map<Integer, List<String>> groupByLength =
  Arrays.stream(words).collect(Collectors.groupingBy(String::length));
System.out.println(groupByLength);

This is just an example, but you get the point. I have an array of words, and then I use streams and Java8 magic to group them in a map by length (exactly what you're trying to do). You get the stream, then collect it to a map, grouping by length of the words, so it's gonna put every 1 letter word in a list under key 1 etc.

You can use the same approach, but you have your words in a list so remember to not use Arrays.stream() but just .stream() on your list.



来源:https://stackoverflow.com/questions/39806876/grouping-of-words-from-a-text-file-to-arraylist-on-the-basis-of-length

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!