Solution 0: Refactoring
, , - . , , , , .
1: ""
, , - . , X , "". - . , . , . ( , Xa Xb , .) , -, , , , .
, , , . , , , X . , . . , .
public final class X implements Comparable<X> {
public static enum Genders { A, B };
private Genders gender;
private final String a;
private final Integer b;
public X(final String a, final Integer b, final Genders gender) {
if (a == null) {
throw new NullPointerException("a");
}
if (b == null) {
throw new NullPointerException("b");
}
if (gender == null) {
throw new NullPointerException("gender");
}
this.a = a;
this.b = b;
this.gender = gender;
}
public Genders getGender() {
return this.gender;
}
public void setGender(final Genders gender) {
if (gender == null) {
throw new NullPointerException("gender");
}
this.gender = gender;
}
@Override
public boolean equals(final Object other) {
if (other instanceof X) {
final X otherX = (X) other;
if (this.gender == otherX.gender) {
switch (this.gender) {
case A:
return this.a.equals(otherX.a);
case B:
return this.b.equals(otherX.b);
default:
throw new AssertionError("unexpected gender");
}
}
}
return false;
}
@Override
public int hashCode() {
switch (this.gender) {
case A:
return this.a.hashCode();
case B:
return this.b.hashCode();
default:
throw new AssertionError("unexpected gender");
}
}
@Override
public int compareTo(final X other) {
switch (this.gender) {
case A:
return this.a.compareTo(other.a);
case B:
return this.b.compareTo(other.b);
default:
throw new AssertionError("unexpected gender");
}
}
@Override
public String toString() {
return String.format("{a: \"%s\", b: %d, gender: %s}",
this.a, this.b, this.gender);
}
}
, .
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
public final class Main {
public static void main(final String[] args) {
final Set<X> theAs = new HashSet<>();
final Set<X> theBs = new TreeSet<>();
theAs.add(new X("alpha", 1, X.Genders.A));
theAs.add(new X("beta", 1, X.Genders.A));
theAs.add(new X("gamma", 2, X.Genders.A));
theAs.add(new X("delta", 2, X.Genders.A));
System.out.println("These are the As:\n");
for (final X x : theAs) {
System.out.println(x);
}
System.out.println();
{
final Iterator<X> iter = theAs.iterator();
while (iter.hasNext()) {
final X x = iter.next();
iter.remove();
x.setGender(X.Genders.B);
theBs.add(x);
}
}
theBs.add(new X("alpha", 3, X.Genders.B));
theBs.add(new X("alpha", 4, X.Genders.B));
System.out.println("These are the Bs:\n");
for (final X x : theBs) {
System.out.println(x);
}
}
}
:
These are the As:
{a: "alpha", b: 1, gender: A}
{a: "delta", b: 2, gender: A}
{a: "beta", b: 1, gender: A}
{a: "gamma", b: 2, gender: A}
These are the Bs:
{a: "alpha", b: 1, gender: B}
{a: "delta", b: 2, gender: B}
{a: "alpha", b: 3, gender: B}
{a: "alpha", b: 4, gender: B}
2:
( , ) new "", .
. (, , .)
public interface X {
public String getA();
public Integer getB();
}
, , , . , ( ) (, , final). equals hashCode Comparable, "" , Object. , (. ).
public final class BasicX implements X {
private final String a;
private final Integer b;
public BasicX(final String a, final Integer b) {
if (a == null) {
throw new NullPointerException("a");
}
if (b == null) {
throw new NullPointerException("b");
}
this.a = a;
this.b = b;
}
@Override
public String getA() {
return this.a;
}
@Override
public Integer getB() {
return this.b;
}
@Override
public String toString() {
return String.format("{a: \"%s\", b: %d}", this.a, this.b);
}
}
- . : Xa Xb. ( ) X, , equals hashCode Comparable.
, - .
abstract class DecoratedX implements X {
private final X x;
protected DecoratedX(final X x) {
if (x == null) {
throw new NullPointerException("x");
}
this.x = x;
}
protected final X getX() {
return this.x;
}
@Override
public final String getA() {
return this.x.getA();
}
@Override
public final Integer getB() {
return this.x.getB();
}
@Override
public final String toString() {
return this.x.toString();
}
}
Xa Xb , . , Xa Xb final.
public final class Xa extends DecoratedX implements X, Comparable<Xa> {
public Xa(final X x) {
super(x);
}
@Override
public boolean equals(final Object other) {
if (other instanceof Xa) {
final Xa otherXa = (Xa) other;
return this.getA().equals(otherXa.getA());
}
return false;
}
@Override
public int hashCode() {
return this.getA().hashCode();
}
@Override
public int compareTo(final Xa other) {
return this.getA().compareTo(other.getA());
}
}
, , ( , ) Xb, , .
final class Xb extends DecoratedX implements X, Comparable<Xb> {
public Xb(final X x) {
super(x);
}
@Override
public boolean equals(final Object other) {
if (other instanceof Xb) {
final Xb otherXb = (Xb) other;
return this.getB().equals(otherXb.getB());
}
return false;
}
@Override
public int hashCode() {
return this.getB().hashCode();
}
@Override
public int compareTo(final Xb other) {
return this.getB().compareTo(other.getB());
}
}
. , , . , ( () ) .
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
public final class Main {
public static void main(final String[] args) {
final List<X> theXs = new ArrayList<>();
final Set<Xa> theXas = new HashSet<>();
final Set<Xb> theXbs = new TreeSet<>();
theXs.add(new BasicX("alpha", 1));
theXs.add(new BasicX("alpha", 1));
theXs.add(new BasicX("beta", 2));
theXs.add(new BasicX("beta", 3));
theXs.add(new BasicX("gamma", 2));
theXs.add(new BasicX("delta", 3));
for (final X x : theXs) {
theXas.add(new Xa(x));
theXbs.add(new Xb(x));
}
System.out.println("These are the As:\n");
for (final X x : theXas) {
System.out.println(x);
}
System.out.println();
System.out.println("These are the Bs:\n");
for (final X x : theXbs) {
System.out.println(x);
}
}
}
:
These are the As:
{a: "alpha", b: 1}
{a: "delta", b: 3}
{a: "beta", b: 2}
{a: "gamma", b: 2}
These are the Bs:
{a: "alpha", b: 1}
{a: "beta", b: 2}
{a: "beta", b: 3}
, : Xb Xa s. Xa Xb BasicX s. " Xa Xb" , , ,
Xb a2b(final Xa xa) {
return new Xb(xa.getX());
}
Xa b2a(final Xb xb) {
return new Xa(xb.getX());
}
. DecoratedX.getX() public, . ( Xa Xb: X. , .)