次のJava試験に備えるために、過去の試験用紙で見つけたこの質問に挑戦するだけです。
モノのペアを表すための汎用クラスPairを提供します。クラスは、コンストラクター、ペアの最初のメンバーを取得するメソッド、ペアの2番目のメンバーを取得するメソッド、ペアの最初のメンバーを設定するメソッド、ペアの2番目のメンバーを設定するメソッドを提供する必要があります。クラスは、ペアの最初のメンバーと2番目のメンバーの2つのタイプでパラメーター化する必要があります。
これはこの質問の正しい実装ですか?
public class Pair<firstThing, secondThing>{
private firstThing first;//first member of pair
private secondThing second;//second member of pair
public Pair(firstThing first, secondThing second){
this.first = first;
this.second = second;
}
public void setFirst(firstThing first){
this.first = first;
}
public void setSecond(secondThing second) {
this.second = second;
}
public thing getFirst() {
return this.first;
}
public thing getSecond() {
return this.second;
}
}
ほとんど。私はそれを次のように書きます:
public class Pair<F, S> {
private F first; //first member of pair
private S second; //second member of pair
public Pair(F first, S second) {
this.first = first;
this.second = second;
}
public void setFirst(F first) {
this.first = first;
}
public void setSecond(S second) {
this.second = second;
}
public F getFirst() {
return first;
}
public S getSecond() {
return second;
}
}
編集:@karmakazeのコメントに同意します。コードはセッターをスキップし、最初と2番目を最終的にして不変に保つ必要があります。
Pairクラスの必要性は通常、より大きなプロジェクトで発生します-現在のプロジェクトに1つを(再)実装しようとしています(以前の実装にはアクセスできないため)。
一般に、インスタンスを作成するための便利な機能を備えた、不変のPOJOにします。例えば:
public class Pair<T,U>
{
public final T first;
public final U second;
public static <T,U> Pair<T,U> of(T first, U second);
}
エンドユーザーが次のように書けるように:
return Pair.of (a, b);
そして
Pair<A,B> p = someThing ();
doSomething (p.first);
doSomethingElse (p.second);
上記のように、Pairクラスは、hashCode()、equals()、オプションであるが有用なtoString()も実装する必要があります。これらのコントラクトがPairクラスでどのようにサポートされるかを説明する必要があります。
Android SDKからの実装です。
/**
* Container to ease passing around a Tuple of two objects. This object provides a sensible
* implementation of equals(), returning true if equals() is true on each of the contained
* objects.
*/
public class Pair<F, S> {
public final F first;
public final S second;
/**
* Constructor for a Pair.
*
* @param first the first object in the Pair
* @param second the second object in the pair
*/
public Pair(F first, S second) {
this.first = first;
this.second = second;
}
/**
* Checks the two objects for equality by delegating to their respective
* {@link Object#equals(Object)} methods.
*
* @param o the {@link Pair} to which this one is to be checked for equality
* @return true if the underlying objects of the Pair are both considered
* equal
*/
@Override
public boolean equals(Object o) {
if (!(o instanceof Pair)) {
return false;
}
Pair<?, ?> p = (Pair<?, ?>) o;
return Objects.equal(p.first, first) && Objects.equal(p.second, second);
}
/**
* Compute a hash code using the hash codes of the underlying objects
*
* @return a hashcode of the Pair
*/
@Override
public int hashCode() {
return (first == null ? 0 : first.hashCode()) ^ (second == null ? 0 : second.hashCode());
}
/**
* Convenience method for creating an appropriately typed pair.
* @param a the first object in the Pair
* @param b the second object in the pair
* @return a Pair that is templatized with the types of a and b
*/
public static <A, B> Pair <A, B> create(A a, B b) {
return new Pair<A, B>(a, b);
}
}
いいえ。
「クラスは2つのタイプでパラメーター化する必要があります...」
彼らは次の点で期待していると思います:
public class Pair<ThingA, ThingB>
編集後はよさそうです。
ただし、実際にはhashCode
メソッドとequals
メソッドを実装して、同じオブジェクトを含む2つのペアが互いに等しくなり、HashMapでキーとして使用できるようにする必要があります。寛大な気分ならtoString
も。これらのメソッドは、指定された要件を満たすために必須ではありませんが、優れたプログラマーが追加するものです。
通常、ジェネリックPair型には2ジェネリック型パラメーターがあり、1つではないため、Pair<String, Integer>
を(たとえば)持つことができます。通常は、IMOの方が便利です。
また、型パラメータには、「もの」よりも従来の名前を考えることをお勧めします。たとえば、Pair<A, B>
またはPair<T, U>
を使用できます。
ゲッターが壊れている
public thing getFirst() {
return thing.first;
}
public thing getSecond() {
return thing.second;
}
thing
はthis
に置き換える必要があります
クラスは、ペアの最初のメンバーと2番目のメンバーの2つのタイプでパラメーター化する必要があります。
パラメーターは1つだけです。
Pair<F,S>
のようなものが必要であり、最初にthing
を使用するFを使用し、2番目にthing
を使用するSを使用します。
Apache Commons Langには一般的なペアの実装があります
https://commons.Apache.org/proper/commons-lang/apidocs/org/Apache/commons/lang3/Tuple/Pair.html
いいえ。それが機能するかどうかを確認するためにコーディングしてみましたか?
要件のこの部分を逃したようです:
クラスは、ペアの最初のメンバーと2番目のメンバーの2つのタイプでパラメーター化する必要があります。
つまり、クラスはおそらく次のように定義する必要があります。
public class Pair<T1, T2>
その他のメソッドはそれに応じて更新されました。 (ちなみに、私はT1とT2を使用してタイプを参照していますが、慣例では、短い1または2文字の識別子が使用されています)。
また、
return thing.first;
そして
return thing.second;
あなたの例のように、thing
はオブジェクトではなく型であるので機能しません。ここで何を返したいか考えてください。メソッドを呼び出す必要さえありますか?
変更を加えたら、コードを記述し、単体テストまたは単純なテストハーネスを記述して、機能するかどうかを確認します。
thing
はType Variableであり、通常とは異なる表記法です。通常、大文字の大文字を1つ使用します(T
のように)。次に、型変数にはメソッドがないため、ゲッターはコンパイルされません。
迅速な改善:すべてのthing
をT
に置き換えます
ゲッターのクイックフィックス:
public T getFirst() {
return first;
}
public T getSecond() {
return second;
}
1つの要件は、ペアのメンバーに2つの異なるタイプを許可することでした。したがって、クラスの署名は次のようになります。
public Pair<S,T> {
private S first;
private T second;
//...
}
私は似たようなものを実装しましたが、静的ビルダーと連鎖セッターを使用しています
public class Pair<R, L> {
private R left;
private L right;
public static <K,V> Pair<K, V> of(K k, V v) {
return new Pair<K,V>(k, v);
}
public Pair() {}
public Pair(R key, L value) {
this.left(key);
this.right(value);
}
public R left() {
return left;
}
public Pair<R, L> left(R key) {
this.left = key;
return this;
}
public L right() {
return right;
}
public Pair<R, L> right(L value) {
this.right = value;
return this;
}
}
私のバージョンのペア。これは比較も処理します。 PS:コードのほとんどはAOSPから取得されます。
package util;
import Java.util.Objects;
public class Pair<F extends Comparable<F>, S extends Comparable<S>>
implements Comparable<Pair<F, S>> {
public final F first;
public final S second;
/**
* Constructor for a Pair.
*
* @param first the first object in the Pair
* @param second the second object in the pair
*/
public Pair(F first, S second) {
this.first = first;
this.second = second;
}
/**
* Checks the two objects for equality by delegating to their respective
* {@link Object#equals(Object)} methods.
*
* @param o the {@link Pair} to which this one is to be checked for equality
* @return true if the underlying objects of the Pair are both considered
* equal
*/
@Override
public boolean equals(Object o) {
if (!(o instanceof Pair)) {
return false;
}
Pair<?, ?> p = (Pair<?, ?>) o;
return Objects.equals(p.first, first) && Objects.equals(p.second, second);
}
/**
* Compute a hash code using the hash codes of the underlying objects
*
* @return a hashcode of the Pair
*/
@Override
public int hashCode() {
return (first == null ? 0 : first.hashCode()) ^ (second == null ? 0 : second.hashCode());
}
/**
* Convenience method for creating an appropriately typed pair.
*
* @param a the first object in the Pair
* @param b the second object in the pair
* @return a Pair that is templatized with the types of a and b
*/
public static <A extends Comparable<A>, B extends Comparable<B>> Pair<A, B> create(A a, B b) {
return new Pair<>(a, b);
}
@Override
public int compareTo(Pair<F, S> that) {
int cmp = this.first.compareTo(that.first);
if (cmp == 0)
cmp = this.second.compareTo(that.second);
return cmp;
}
}