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));
}
}
}
这种做法是对的吗?
说明:
答案 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+")
其次,您不需要任何临时数据结构。您可以在从文件中读取行后立即将单词添加到地图中。 arr
和lengths
列表在这里实际上没用,因为除了临时存储之外它们不包含任何逻辑。您正在使用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
}
但正如我已经提到过的,你根本不需要它。这只是出于教育目的。