3

プログラミングのタスクを実行中に少し問題が発生しました。ファイルからいくつかの行を読み取り (これまでのところ問題ありません)、トークン化したいと考えています。各行には約 4 つのトークンがあり、それぞれがリスト内の場所を見つける必要があります。最後に、すべての行もリストに含める必要があります。

これを明確にするための小さな例:

ファイルの内容:

フー
ブーバービイブウバア

出力:

[[フー、ブー、バー]、[ビー、ブウ、バア]]

そして、私が扱っているコードはheresです

String fileContent = fileloader(file.toString());
List<String> linesList = new ArrayList<String>();
String[] lines = fileContent.split("\n"); 
for(String line:lines){
  String[] splittedLine = line.split("\t");
  for(String words:splittedLine){
    linesList.add(words);
  }
  lexiconContent.add(linesList); 
  linesList.removeAll(linesList);
}

最初の反復はうまく機能するので、参照に問題があると思います! しかし、2 回目の反復では、実際の2 番目のコンテンツも最初の(0)リスト位置にコピーされます。

最後に私は次のようなものを得ました[[], [], [], []]

4

2 に答える 2

3

問題は、リストを 1 つしか作成せず、そのリストへの参照を外側のリストに追加して、反復ごとに変更することです。したがって、そのリストに対して行われた最終的な変更は、すべての参照に反映されます。

この問題linesListは、ループのたびに新しいものを作成することで解決できます: -

List<String> linesList = null;  // Don't initialize here
String[] lines = fileContent.split("\n"); 

for(String line:lines){
    String[] splittedLine = line.split("\t");
    linesList = new ArrayList<String>(); // Initialize a new list everytime.

    for(String words:splittedLine){
        linesList.add(words);
    }
    lexiconContent.add(linesList); 
}

そして、はい、 for ループを次のように単純化することもできます: -

for(String line:lines){
    String[] splittedLine = line.split("\t");
    lexiconContent.add(new ArrayList<String>(Arrays.asList(splittedLine))); 
}

このように、配列を反復処理して個別の要素を List に追加する必要はありません。実際、中間リストはまったく必要ありません。

于 2013-01-30T19:58:46.013 に答える
0

あなたのコードでは..ループ内の反復ごとに新しい ArrayList を作成する代わりに:外側のループの最初の反復から使用for(String line:lines)した古いオブジェクトに (ネストされたループ内で) 単語を追加し、同じ参照値を格納するだけです。 ArrayListArrayListのすべての後続のインデックスで。また、外側のループの各反復の終わりに、 .So 最後に N 個のエントリが残ります...ここで、lexiconContent の各インデックスの要素は参照値にすぎませんEmpty である ArrayList(lineList) の単一オブジェクトの!!!lexiconContentlinesListlexiconContent

You should use following code instead:
String fileContent = fileloader(file.toString());
List<String> linesList = null;
String[] lines = fileContent.split("\n"); 
for(String line:lines){
  List<String> linesList = new ArrayList<String>();
  String[] splittedLine = line.split("\t");
  for(String words:splittedLine){
    linesList.add(words);
  }
  lexiconContent.add(linesList); 
}
于 2013-01-30T20:27:12.513 に答える