基于长度将文本文件中的单词分组到Arraylist

时间:2016-10-01 12:57:59

标签: java arraylist hashmap

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));
        }
    }

}

这种做法是对的吗?

说明:

  1. 将所有单词加载到ArrayList。
  2. 然后遍历每个索引并检查单词的长度将其添加到包含该长度的字符串的ArrayList中,其中这些ArrayList映射到具有其所包含的单词长度的散列映射中。

2 个答案:

答案 0 :(得分:1)

您的方法很长,令人困惑,难以调试,而且我认为它的性能不佳(请查看contains方法)。检查一下:

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);

这只是一个例子,但你明白了。我有一系列单词,然后我使用流和Java8魔法按照长度将它们分组(确切地说是你想要做的)。你得到了流,然后把它收集到一张地图,按照单词的长度进行分组,这样就可以将每个1个字母的单词放在键1等下的列表中。

您可以使用相同的方法,但是您将单词列在列表中,因此请记住不要在列表中使用Arrays.stream(),而只使用.stream()

答案 1 :(得分:1)

首先,当您将整行作为单词处理时,您的代码仅适用于包含一个单词的文件。为了使您的代码更加通用,您必须通过将每个行拆分为单词来处理每一行:

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

其次,您不需要任何临时数据结构。您可以在从文件中读取行后立即将单词添加到地图中。 arrlengths列表在这里实际上没用,因为除了临时存储之外它们不包含任何逻辑。您正在使用lengths列表来存储已添加到hm地图的长度。通过调用hm.containsKey(s.length())可以达到相同的目的。

还有一条关于代码的评论:

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

当你有一个这样的循环时,你只需要找到任何元素的某些条件为真,你不需要在找到条件时继续循环。您应该在if语句中使用break关键字来终止循环块,例如

    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
    }

但正如我已经提到过的,你根本不需要它。这只是出于教育目的。