• ベストアンサー

Listからのnull要素を削除方法は?

次のリストに入っているnull要素を削除する方法をお教え下さい。  List<String> lst = new ArrayList<String>(); while (lst.remove(null)); や for (int i=0; i < lst.size();i++) {  if (lst.get(i) == null ) lst.remove(i); } ではException in thread "main" java.lang.UnsupportedOperationException が起こります。 2011 Nov. 27.

  • Java
  • 回答数5
  • ありがとう数4

質問者が選んだベストアンサー

  • ベストアンサー
  • salsberry
  • ベストアンサー率69% (495/711)
回答No.1

実際に試してみましたが、lst.remove(null)やlst.remove(i)で問題なくnullをList<String>から削除できますよ。 for (int i=0; i < lst.size();i++) { ... }のほうは、lstにnullが連続して入っていた場合に期待したとおりに動かないと思いますが。

RASUM2
質問者

お礼

salsberry様、ありがとうございます。 今まで見ていたプログラムの中では質問のとおりなのですが、別に書いて試してみたら頂いた回答のとおりの動きです。 悲しいかな、今まで見ていたプログラムのどこが違うのかがわからない状況です。 2011 Nov. 28.

その他の回答 (4)

noname#147388
noname#147388
回答No.5

いいえ Arrays.asList で作成したリストはその状態では Iterator にしたところで削除は不可能です。 実際うちがおもったのは。 https://ideone.com/eHRHK の動作

  • mpro-gram
  • ベストアンサー率74% (170/228)
回答No.4

No3回答者です。前回回答に間違いがったので、訂正 「終端条件を再計算しない」→ 自分がチェックするとき、終端に定数を入れてしまってただけでした。lst.size() なら判定の度に現在数を数えます。(他の言語と勘違いもしてたせい)。 あと、jdk1.5 では list.remove(null) は、JREのversion によっては、Unsupported が発生します。たぶん引数の型が不明となるからじゃないでしょうか。型を明示されてる変数で中身がnullなのはとおりますし。 昨日vistaで実行テストしてたんだけど、たしか新しいversionのはず(今ちょっと確認できず)で、ご質問と同様のエラー出たけど、古いjre1.5.0のままのxpの方で実行してみたらエラーになりませんでした。eclipseの設定違いの可能性もあるけど、一応そういうこともあるので、型宣言されてる変数で入れた方がベターのようです。

  • mpro-gram
  • ベストアンサー率74% (170/228)
回答No.3

ArrayList の要素番号って、途中を削除したら、番号ふり直して詰め込まれるんじゃなかったかな? for構文で先頭から検索して途中削除すると、要素数が変わるが、javaでは、終端条件を再計算しないので、要素がすでに無い(null要素ではなくて、要素番号がない)番号にアクセスしてしまうので、 Exception in thread "main" java.lang.IndexOutOfBoundsException: になる。 また、削除直後の要素は、番号が一つ減ってるので次のiでは、さらにその次にあった要素にマッチしてしまう、つまりnull連続の時に取りこぼす。 よって、後ろから検索して削除するのがよい(i=lst.size()-1; i>=0; i--)

RASUM2
質問者

お礼

mpro-gram様、ありがとうございます。 今まで見ていたプログラムの中では質問のとおりなのですが、別に書いて試してみたらforループでnull要素を削除できました。 いじっているプログラムの問題がわからない状態となりましたので、とりあえずお礼までとなります。 詳しい解説をありがとうございます。 2011 Nov. 28.

noname#147388
noname#147388
回答No.2

エスパー的感で リストの作り方は Arrays#asList(E[]) では 要素の更新がUnsupportedOperationExceptionとなるはずです。 リストからデータを削除する場合、 イテレーターにしてからイテレーターで削除してください。

RASUM2
質問者

お礼

alice_asahina様、ありがとうございます。 当該のlstは、別のクラスの中でaddメソッドで要素を入れ、クラスの返り値としてもらっているものです。これはArrays#asList(E[])での作成とは異なるかと思います。 Arrays#asList(E[])で作ったリストでもイテレータで削除できるのですね。勉強になりました。 2011 Nov. 28.

関連するQ&A

  • javaプログラミングの質問です。

    http://questionbox.jp.msn.com/qa1030602.html?StatusCheck=ON に載っている、プログラムを以下のようにQuestionというクラスで実行してみたところ、 import java.io.*; class Question{ public static void main(String Args[]){ BufferedReader reader = null; String strArray[][] = new String[4][4]; String fileName = "foo.txt"; int i = 0; int j = 0; try{ reader = new BufferedReader ( new FileReader(fileName) ); String line; while ( (line = reader.readLine() ) != null ){ StringTokenizer st = new StringTokenizer ( line ); while ( st.hasMoreTokens() ){ strArray[i][j] = st.nextToken(); System.out.print ( strArray[i][j] + " " ); j ++; } j = 0; i ++; System.out.println (""); } } catch ( Exception e ){ System.out.println ( e.toString() ); } } } Exception in thread "main" java.lang.Error: コンパイル問題が未解決です。 StringTokenizer を型に解決できません。 StringTokenizer を型に解決できません。 というエラーが出ます。 このサイトの質問者はうまくいっているようなのですが、私のコンパイラがうまく動いていないのでしょうか? java version "1.6.0_07" を使っていて、Eclipseを用いてコンパイルをしたりしています。 どなたかご指摘をどうぞよろしくお願いいたします。

    • ベストアンサー
    • Java
  •  Exception in thread "main" java.la

     Exception in thread "main" java.lang.StackOverflowError というエラーが出ます  moji()にtestという変数をいれてやり、mainから、書かそうとしていますが、  Exception in thread "main" java.lang.StackOverflowError というエラーが出ますが、何故かわかりません。  宜しくお願いします。 ************************************************************ public class ArgsTest2 { public static void main(String args[]) { moji(); } public static void moji() { String[] test = {"abcde","fghij"}; main(test); } }

    • ベストアンサー
    • Java
  • ArrayListを使った多次元配列の作成について

    ArrayListで可変長配列を扱っているのですが、 2次元可変長配列を用いる必要が出てきたので、 下記のように変更したのですがうまくいきません。 何が悪いのか教えていただけませんでしょうか? ----------------------------------------- ArrayList cars=new ArrayList(); cars.add("フェラーリ"); cars.add("ポルシェ"); cars.add("メルセデスベンツ"); for(int i=0;i<cars.size();i++){  String str=(String)cars.get(i);  System.out.println(str);} ----------------------------------------- 上記から下記のように変更しました。 ----------------------------------------- ArrayList[] cars=new ArrayList[3]; cars[0].add("フェラーリ"); cars[0].add("ポルシェ"); cars[0].add("メルセデスベンツ"); for(int i=0;i<cars[0].size();i++){  String str=(String)cars[0].get(i);  System.out.println(str);} ----------------------------------------- エラーは「Exception in thread "main" java.lang.NullPointerException」です。 どうやら初期配列が10ではなく3となってしまっているようです。

    • ベストアンサー
    • Java
  • while文の表示

    こんにちは 今DB接続し DBからデータを表示するのを勉強しています public String[][] selectExec(String sql) throws SQLException{ Statement smt = con.createStatement(); //ステートメントオブジェクト作成 SQL文を送るために作成 ResultSet aa=smt.executeQuery(sql); //SQLから要素取得 ArrayList<String> TESTNO = new ArrayList<String>(); //TESTNO用ののArrayList作成 ArrayList<String> NAME = new ArrayList<String>(); //KAME用 ArrayList<String> KANA = new ArrayList<String>(); //KANA用 while(aa.next()){ //Resultsetが最終行になるまで実行 TESTNO.add(aa.getString("TESTNO")); NAME.add(aa.getString("NAME")); KANA.add(aa.getString("KANA")); } aa.close(); //使い終わったリザルトクローズ smt.close(); //ステートメントクローズ      //オブジェクトの解放 return hairetu(TESTNO,NAME,KANA); public String[][] selectExec(String sql, int fromIdx,int toIdx) throws SQLException{ String[][]all=selectExec(sql); ArrayList list = new ArrayList(Arrays.asList(all[0])); ArrayList list1 = new ArrayList(Arrays.asList(all[1])); ArrayList list2 = new ArrayList(Arrays.asList(all[2])); int i=1; while(i<fromIdx){ //指定された前のリスト削除 list.remove(0); list1.remove(0); list2.remove(0); i++; } while(toIdx<list .size()){ //指定されたあとのリスト削除 list .remove(toIdx); list1.remove(toIdx); list2.remove(toIdx); toIdx++; } return hairetu(list ,list1,list2); public String[][] hairetu(ArrayList T,List N ,List K){ String[][]all=new String[3][T.size()]; all[0] = (String[])T.toArray(new String[0]);//配列TSETNOに収納 all[1] = (String[])N.toArray(new String[0]);//配列NAMEに収納 all[2] = (String[])K.toArray(new String[0]);//配列KANAに収納 return all; selectExec(String sql)で全表示 selectExec(String sql, int fromIdx,int toIdx) で列を何行~何行を指定 でリストに変換、リスト削除して 二次元配列にもどしているのですが たとえば 1~5を指定すると 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 6 6 6 8 8 8 ↑のように 5ひとつとばしで表示されます while文の書き方がわるいのでしょうか・・・・ アドバイスお願いします

    • ベストアンサー
    • Java
  • trim()メソッドの使用方法とキャストの仕方について

    こんばんは、今回はtrim()メソッドの使用方法とキャストの方法についてお伺い致します。 trimメソッドを使用して文字列の前後の空白を削除したいのですが、 通常 String str = " 「こんにちは」"; str = str.trim(); とコーディングしコンパイルして表示するとちゃんと「こんにちは」となるのすですが、これが ArrayList list = new ArrayList(); BufferedReader br= new BufferedReader(new FileReader(Test.txt); while((str = br.readLine()) !=null){ str = str.trim(); list.add(str); } br.close(); とコーディングしコンパイルは通るのですが、 「こんにちは」のままで"「"の前にある空白が削除されてません。 私なりに「型」の違いでが原因ではないかと思い、java.io.ArrayList型からjava.lang.String型へキャストしようとしているのですが、コンパイルエラーが出てしまします。 プログラムコードは ArrayList list = new ArrayList(); String s; s = (String)list; としています。 エラー内容は ScheduleControlCall.java:142: 変換できない型 出現: java.util.ArrayList 要求: java.lang.String s = (String)list; ^ エラー 1 個 となっています。 度々ですが、ご指導お願い致します。

    • ベストアンサー
    • Java
  • C++ リストの末尾要素の削除

    連結リストの末尾の要素を削除するプログラムを教えてください。 自分で何度も書き直してみたのですが、どうしてもうまくうごきません。 自分で書いた現状が以下のものですが、止まってしまいます。 void List::removeLast(){ if (head == NULL)return; Cell *p = head; Cell *prev = NULL; while (p!= NULL){ prev = p; p = p->next; } delete prev; } 以下のプログラムが動かすにはremoveLast()をどう変えたらよいのでしょうか? よろしくお願いします。 #include <iostream> using namespace std; // クラスの宣言 class Cell { friend class List; // Listクラスから,このクラスに自由にアクセスできるようにする private: int data; // データ Cell *next; // 次のセルのアドレスを指すポインタ public: Cell(int _data, Cell *n = NULL){ data = _data; next = n; } }; class List { private: Cell *head; // 連結リストの先頭要素のアドレスを指すポインタ public: List(){ head = NULL; }; ~List(){ while (head != NULL)removeFirst(); } void addFirst(int data){ head = new Cell(data, head); } void removeFirst(){ if (head == NULL)return; Cell *removed = head; head = head->next; delete removed; } void removeLast(); void print(){ for (Cell *p = head; p != NULL; p = p->next){ cout << p->data << ' '; } cout << endl; } }; // 連結リストの末尾要素を削除する関数 void List::removeLast() { //この部分です } int main() { List l1; for (int i = 0; i < 10; i++) { l1.addFirst(i); } l1.print(); l1.removeLast(); l1.print(); l1.removeLast(); l1.print(); l1.removeLast(); l1.print(); return 0; } 要求される実行結果は以下の通りです リストの内容: 9 8 7 6 5 4 3 2 1 0 リストの内容: 9 8 7 6 5 4 3 2 1 リストの内容: 9 8 7 6 5 4 3 2 リストの内容: 9 8 7 6 5 4 3

  • 配列とwhileを使った2重ループを使って書きたい

    今JAVAの勉強をしているのですが、「以下のような画面を表示するコードをint型2次元配列とwhileを使った2重ループを使って書いてください。」 ======================================= a[0][0]:1 a[0][1]:2 a[1][0]:3 a[1][1]:4 ======================================= の問題をやっているのですが実行してみると a[0][0]:1 a[1][1]:4 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2 at exsercise141.java.Exsercise141Java.main(Exsercise141Java.java:32) Java Result: 1 ビルド成功(合計時間: 0秒) と表示されてしまい、a[0][1]:2とa[1][0]:3が表示されません。 コードは以下のとおりです。 public static void main(String[] args) { // TODO code application logic here int i=0; int j=0;//変数を宣言 int B [] [] = new int [2] [2];//2次元配列を宣言 //======================================== B [0] [0] = 1;// B [0] [1] = 2; //========================================== B [1] [0] = 3; B [1] [1] = 4; //========================================== while(i<=3) { while(j<=3) { System.out.println("a["+i+"]["+j+"]:"+B[i][j]); i++; j++; } } } } どのようにすればa[0][1]:2とa[1][0]:3も表示されますか? ご教授願います。 ちなみにNetBeansを使用しております。 よろしくお願いします。

    • ベストアンサー
    • Java
  • ListのItemListenerについて

    50音のリストから選択したタイトルの画像を表示するようなプログラムを作ろうと思っているのですが、ItemListenerの2種類以上の使い方?が分かりません。 左側のChoiceからListの内容は書き換えることが出来たのですが、真ん中のListから右のListを書き換え、更には右のListから下部へ画像を表示させたいのです。 この場合どのように記入すればいいのか教えてください。お願いします。 以下拙いですが自分の書いた部分です import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class Test extends Applet implements ItemListener{ Panel p[]=new Panel[1]; Choice c1; String s[]={"あ","い","う","え","お","か","き","く","け","こ", "さ","し","す","せ","そ","た","ち","つ","て","と", "な","に","ぬ","ね","の","は","ひ","ふ","へ","ほ", "ま","み","む","め","も","や","ゆ","よ","","", "ら","り","る","れ","ろ","わ","","","","",}; List lst1,lst2; int i; public void init() { p[0]=new Panel(new GridLayout(1,3)); c1=(Choice)p[0].add(new Choice()); for (i=0;i<50;i=i+5) c1.add(s[i]+"行"); c1.addItemListener(this); lst1=(List)p[0].add(new List(5)); lst1.add(s[0]); lst1.add(s[1]); lst1.add(s[2]); lst1.add(s[3]); lst1.add(s[4]); lst1.addItemListener(this); lst2=(List)p[0].add(new List(5)); lst2.addItemListener(this); add(p[0]); } public void itemStateChanged(ItemEvent e){ Choice c1=(Choice)e.getSource(); String str=(String)c1.getSelectedItem(); if(str.equals("あ行")){ lst1.removeAll(); for(i=0;i<5;i++){ lst1.add(s[i]); } lst2.removeAll(); } else if(str.equals("か行")){ lst1.removeAll(); for(i=5;i<10;i++){ lst1.add(s[i]); } lst2.removeAll(); } 以下わ行まで書いてあります } public void destroy() { } }

    • ベストアンサー
    • Java
  • C++ 連結リストの要素の削除について

    リストで任意の場所の要素を削除するプログラムを考えているのですが、どうしてもその部分のプログラムにmain関数通りの動きをさせる方法が分かりませんでした。いろいろ試してみたのですが、どこかしらでおかしくなってしまうのです。 以下に私がつくった途中までのプログラムを示すので、removeAt(int index)の中身の例を教えて頂きたいのです。よろしくお願い致します。 #include <iostream> using namespace std; // クラスの宣言 class Cell { friend class List; // Listクラスから,このクラスに自由にアクセスできるようにする private: int data; // データ Cell *next; // 次のセルのアドレスを指すポインタ public: Cell(int _data, Cell *n = NULL){ data = _data; next = n; } }; class List { private: Cell *head; // 連結リストの先頭要素のアドレスを指すポインタ public: List(){ head = NULL; }; ~List(){ while (head != NULL)removeFirst(); } void addFirst(int data){ head = new Cell(data, head); } void removeFirst(){ if (head == NULL)return; Cell *removed = head; head = head->next; delete removed; } void removeAt(int index); void print(){ for (Cell *p = head; p != NULL; p = p->next){ cout << p->data << ' '; } cout << endl; } }; // 連結リストの index 番目の要素を削除する関数 void List::removeAt(int index) { //この部分です } int main() { List l1; for (int i = 0; i < 10; i++) { l1.addFirst(i); } l1.print(); l1.removeAt(0); // リストの先頭要素で動作確認 l1.print(); l1.removeAt(2); l1.print(); l1.removeAt(4); l1.print(); l1.removeAt(17); // リストの要素数より大きな引数で動作確認 l1.print(); l1.removeAt(0); // リストの先頭要素で動作確認 l1.print(); l1.removeAt(6); // リストの要素数より大きな引数で動作確認 l1.print(); l1.removeAt(5); l1.print(); return 0; } 要求される実行結果は以下の通りです リストの内容: 9 8 7 6 5 4 3 2 1 0 リストの内容: 8 7 6 5 4 3 2 1 0 リストの内容: 8 7 5 4 3 2 1 0 リストの内容: 8 7 5 4 2 1 0 リストの内容: 8 7 5 4 2 1 0 リストの内容: 7 5 4 2 1 0 リストの内容: 7 5 4 2 1 0 リストの内容: 7 5 4 2 1

  • 配列の値の参照について

    下記のプログラムの-------------で囲まれた部分が、コンパイルは通るのですが実行すると"value[1][0]"以降が参照できません(ここではcount=3 となっています)。 for文を使わずに"System.out.println(value[1][0])"とすると値を取り出せるのですが…。 実行時のエラーは Exception in thread "main" java.lang.ArrayIndexOutOfBoundException: 3 です。 ソースコードをそのまま載せて長文になってしまい申し訳ありません。 プログラム初心者なので、些細なことでもいいので回答お願いします。 import java.util.*; import java.io.*; public class Search { static String dataFileName = "CityData.txt"; ArrayList<String> array = new ArrayList<String>(); GetDataCount gdc = new GetDataCount(dataFileName); int count = gdc.getCount(); int count2 = 0; String[][] value = new String[count][3]; public Search(String dataFileName){ try{ BufferedReader reader = new BufferedReader( new FileReader(dataFileName) ); String line = ""; while((line = reader.readLine()) != null){ Vector<String> variable = readLine(line); System.out.println(variable); count2++; } }catch(IOException e){ System.out.println(e); } //---------------------------------------------------------- for (int i=0; i<count2; i++){ for (int j=0; i<3; j++){ System.out.println(value[i][j]); } } //---------------------------------------------------------- } public Vector<String> readLine( String line ){ StringTokenizer st = new StringTokenizer( line, "," ); Vector<String> variable = new Vector<String>(); for( int i=0 ; i<3 ; i++ ){ String data = st.nextToken(); variable.addElement( data ); value[count2][i] = data; System.out.println(value[count2][i]); } return variable; } public class GetDataCount{ int count = 0; public GetDataCount(String dataFileName){ try{ BufferedReader reader = new BufferedReader( new FileReader(dataFileName) ); String line = ""; while((line = reader.readLine()) != null){ count++; } }catch(IOException e){ System.out.println(e); } } public int getCount(){ return count; } } public static void main(String[] args){ new Search(dataFileName); } }

専門家に質問してみよう