「動的 ArrayLists」に関連する問題があります。ユーザー名とそのデータを含むリストがあります。個別のユーザー名ごとに、このユーザーのすべてのデータを含む単一のリストを作成したいと考えています。たとえば、次のような配列リスト (ユーザー名、ツイート) があります。その後、2 つのリストを作成します。1 つは kostas と彼のツイート、もう 1 つは lefteris とそのツイート (2 ツイート) のリストです。親配列リストには、20 個以上の異なるユーザー名が含まれる場合があります。どうやってやるの ?
4 に答える
いくつかのライブラリは、関数型言語が提供するものに沿って、Javaに優れたコレクション処理機能を追加します。そのようなライブラリの1つがGoogleGuavaです。Guavaは、必要な方法で物事をグループ化するのに適したMultiMapを提供します。また、 MultiMaps.index()のように、リストの要素に関数を適用してキーを計算することにより、リストからマップにアイテムを収集するユーティリティメソッドも多数あります。このようなサポートにより、問題を解決するのに数行のコードと1つの関数実装(他の言語ではクロージャ)が必要になります。
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import java.util.Arrays;
import java.util.List;
public class Tweets {
public static final int NAME = 0;
public static final int TWEET = 1;
public static void main(String[] args) {
List<String> namesAndTweets = Arrays.asList(
"lefteris", "Plays ball",
"Kostas", "Plays basketball",
"lefteris", "Nice weather");
List<List<String>> nameTweetPairs =
Lists.partition(namesAndTweets, 2);
Multimap<String, List<String>> namesAndTweetsByName =
Multimaps.index(nameTweetPairs, get(NAME));
Multimap<String, String> tweetsByName =
Multimaps.transformValues(namesAndTweetsByName, get(TWEET));
System.out.println(tweetsByName);
}
private static Function<List<String>, String> get(final int n) {
return new Function<List<String>, String>() {
@Override
public String apply(List<String> nameAndTweet) {
return nameAndTweet.get(n);
}
};
}
}
出力:
{lefteris=[Plays ball, Nice weather], Kostas=[Plays basketball]}
更新:コードをもう少し説明するために、3つの基本的な手順があります。
- 名前とツイートがすべて混在しているリストを取得し、 Lists.partition()を使用して(name、tweet)のペアに分割します。
- MultiMaps.index()を使用して、名前をマップキーとして、ペアからMultiMapを作成します。これにより、マップキーが名前であり、マップ値が(name、tweet)ペアであるマップが得られます。
- MultiMaps.transformValues()を使用して、マップ値を(name、tweet)ペアからツイートのみに減らします。
PSは、私の機能を実行する組み込み関数があるかどうかを誰かが知ってget()
いますか?提供すべき便利な機能のようですが、どこにも見つかりません。
次のデータ構造を使用します。
HashMap<String, ArrayList<String>>
次に、プロパティが単一のアイテムである場合、各名前にキー付けされたプロパティの「動的」リストを操作できます。
Lefteris->("Plays ball", "Nice weather",...)
Kostas->("Plays basketball",...)
プロパティがキーと値のペアの場合は、次のようにします。
HashMap<String, HashMap<String, Object>>
次のようなデータ:
Lefteris->(Sport->"Plays ball", Weather->"Nice",...)
Kostas->(Sport->"basketball",...)
ファイルからアイテムを解析するため、次のことができます。
特定のユーザー名に関連付けられたツイートを含むマップを作成する
Map<String,List<String>> userTweets = new HashMap<String,List<String>>();
次に、ツイートを特定のユーザーに関連付けるメソッドを用意し、マップに既に追加されていることを確認し、追加されていない場合は追加します。
public void addTweetToUser(String user, String tweet) {
if(userTweets.containsKey(user))
userTweets.get(user).add(tweet);
else {
List<String> newUserTweets = new LinkedList<String>();
newUserTweets.add(tweet);
userTweets.put(user, newUserTweets);
}
}
UserTweet
さらに、以下を含むオブジェクトを作成することでこれを改善できます。
public class UserTweet {
private String user;
private String tweet;
//Constructor, Setters & Getters or all of them
}
次に、代わりにaddTweetToUser
メソッドにUserTweet
パラメーターを含めることができます。
特定のユーザーのつぶやきを知りたい場合は、userTweets
マップから対応するリストを取得するだけです。念のため、ツイートを削除したり、ユーザーを削除したりする方法もあります。
代わりにハッシュマップまたはハッシュセットを使用することをお勧めします。なぜなら、何かをペアで保存する必要がある場合、ハッシュは完璧な解決策だからです......