前提・実現したいこと
list.set(list.indexOf("i"), "I");
を使用して、53番目の位置の値を変更したい。
ですが、エラー
Exception in thread "main" java.lang.NullPointerException
と指定した場所がありませんと表示されます…。
どうしたら53番目の値を変更できますか?
またリスト内に含まれる「i」を検索して、
大文字に変える方法はございませんか?
iのインデックスは53です 後ろから調べたiのインデックスは53
該当のソースコード
java
1import java.io.*; 2import java.util.*; 3public class Q { 4 // 「1つ以上のスペース、ピリオド、コンマ、セミコロンのどれか」という意味 5 // |は区切ったもののどれかという意味で、.は単にピリオドです(文字列表記する都合上、バックスラッシュが2つ必要) 6 private static final String SEPARATOR = "(\s+?|\.|,|;)"; 7 /** 8 * データファイルを開く 9 * resources/q003/data.txt 10 */ 11 private static InputStream openDataFile() { 12 //getResourceAsStreamメソッドを利用すると、リソースファイル(設定ファイルなどのこと)を簡単に読み込むことができる 13 return Q.class.getResourceAsStream("data.txt"); 14 } 15 public static void main(String[] args){ 16 // 集計 17 //カウントには以下のMap<String, Integer>を使用 18 Map<String, Integer> map = new HashMap<>(); 19 try ( 20 /* 21 ファイルの読み込み main配下にあるresourcesからファイルを取得している 22 FileReaderを使ってファイルを読み込む場合には、1文字読み込んでは1文字処理して、と言うのを繰り返すため、非常に効率が悪い 23 */ 24 FileReader fr = new FileReader(Q.class.getResource("data.txt").getFile()); 25 /* 26 ファイルの読み込み 27 なぜ最初からこのクラスを使わないかというと、このクラスはFileReaderクラスを拡張する形で利用するため。 28 FileReaderクラスの持つ基本機能でファイルから読み込みは行うが、 29 それにBufferedReaderクラスをかぶせて使うことでまとめて読み込む機能を持てるようになる 30 */ 31 BufferedReader br = new BufferedReader(fr)){ 32 /* 33 テキストを1行単位で読む 34 1行まとめて読むための"readLine"メソッドが用意されている。 35 注意する点は、改行文字は読み込んだ文字に含まれない事 36 よって1行ごとに、改行を含まないテキストを読み込んでString型の値として返す 37 */ 38 String line; 39 //テキストファイルの読み取りの箇所ではreadLine()で行を取得 40 while ((line = br.readLine()) != null) { 41 /* 42 全て大文字に変換する。 43 */ 44 String resultline = line.toLowerCase(); 45 //splitメソッドでword[]に分割して格納していく。 46 String[] words = resultline.split(SEPARATOR); 47 //繰り返し処理 48 for (String word : words) { 49 //もしwordがからでないなら… 文字列が空かどうかを判定する – isEmptyメソッド 50 //分解後に空白1文字が残る場合に備え、単語の出現数のカウントではisEmpty()メソッドを使用 51 if (!word.isEmpty()) { 52 /* 53 containsKeyメソッドは、指定したキーが存在するか確認を行い、キーが存在する場合は「true」を返します 54 Map.containsKey(検索するキー) 55 キー→単語 56 値 →出現数 57 単語wordが与えられたときの処理は以下の考え方。 58 単語がMapのキーに含まれている場合、出現数を加算する。 59 単語がMapのキーに含まれていない場合、以下をMapに格納する。 60 キー word 61 値 1 62 */ 63 if (map.containsKey(word)) { 64 /* 65 要素を取り出すためにgetメソッドを使用する。 get(Object key) 66 要素を格納するためにputメソッドを使用する。 put(K key, V value) 67 */ 68 int count = map.get(word) + 1; 69 map.put(word, count); 70 } else { 71 map.put(word, 1); 72 } 73 } 74 } 75 } 76 } catch (FileNotFoundException e) { 77 System.out.println("ファイルが見つかりませんでした。"); 78 } catch (IOException e) { 79 System.out.println("読み取りに失敗しました。"); 80 } 81 /* 82 アルファベット辞書順に並び変えて出力 83 条件 84 * - "I"以外は全て小文字で扱う("My"と"my"は同じく"my"として扱う) 85 * - 単数形と複数形のように少しでも文字列が異れば別単語として扱う("dream"と"dreams"は別単語) 86 * - アポストロフィーやハイフン付の単語は1単語として扱う("isn't"や"dead-end") 87 */ 88 List<String> list = new ArrayList<>(); 89 int maxLengthOfSpelling = 0; 90 for (String key : map.keySet()) { 91 list.add(key); 92 if (maxLengthOfSpelling < key.length()) { 93 maxLengthOfSpelling = key.length(); 94 } 95 } 96 /* 97 アルファベット順にソート 98 "I"以外は全て小文字で扱う("My"と"my"は同じく"my"として扱う) 99 Comparatorインターフェースを用いた方法ではソートするための条件をプログラマが決めることができる。 100 複雑な条件でのソートやオブジェクトの並び替えを特定のルールに沿って行いたいときは、この方法を用いる 101 */ 102 Collections.sort(list, new Comparator<String>() { 103 @Override 104 public int compare(String s1, String s2) { 105 return s1.compareToIgnoreCase(s2); 106 } 107 }); 108 /* 109 どこかのタイミングで 格納されているiを見つけ出し、 110 toUpperCaseメソッドで、小文字を大文字に変換すると解決する。 111 */ 112 System.out.println("iのインデックスは" + list.indexOf("i") + "です"); 113 System.out.println("後ろから調べたiのインデックスは"+list.lastIndexOf("i")); 114 // list.set(list.indexOf("i"), "I"); 115 // 全部の値を出力 116 String format = "%-" + maxLengthOfSpelling + "s= %3d"; 117 for (String word : list) { 118 int count = map.get(word); 119 //出力の回数を制限するなら、ここで if (出現させたい件数 <= count)で可能 120 System.out.printf(format, word, count); 121 System.out.println(); 122 } 123 } 124}
試したこと
デバッグで、listの53番目に"i"が格納されていることを確認いたしました。
なぜインデック番号53番目に入っているのに値が変更できないのでしょうか?
回答1件
あなたの回答
tips
プレビュー