Вот объектно-ориентированное решение, класс с именем Mapper<S,T>
, который отображает значения любого типа, который реализуется сопоставимо с любым целевым типом.
Синтаксис:
Mapper<String, Integer> mapper = Mapper.from("a","b","c").to(1,2,3);
// Map a single value
System.out.println(mapper.map("beef")); // 2
// Map a Collection of values
System.out.println(mapper.mapAll(
Arrays.asList("apples","beef","lobster"))); // [1, 2, 3]
Код:
public class Mapper<S extends Comparable<S>, T> {
private final S[] source;
private final T[] target;
// Builder to enable from... to... syntax and
// to make Mapper immutable
public static class Builder<S2 extends Comparable<S2>> {
private final S2[] data;
private Builder(final S2[] data){
this.data = data;
}
public <T2> Mapper<S2, T2> to(final T2... target){
return new Mapper<S2, T2>(this.data, target);
}
}
private Mapper(final S[] source, final T[] target){
final S[] copy = Arrays.copyOf(source, source.length);
Arrays.sort(copy);
this.source = copy;
this.target = Arrays.copyOf(target, target.length);
}
// Factory method to get builder
public static <U extends Comparable<U>, V> Builder<U> from(final U... items){
return new Builder<U>(items);
}
// Map a collection of items
public Collection<T> mapAll(final Collection<? extends S> input){
final Collection<T> output = new ArrayList<T>(input.size());
for(final S s : input){
output.add(this.map(s));
}
return output;
}
// map a single item
public T map(final S input){
final int sourceOffset = Arrays.binarySearch(this.source, input);
return this.target[
Math.min(
this.target.length-1,
sourceOffset < 0 ? Math.abs(sourceOffset)-2:sourceOffset
)
];
}
}
Редактировать: окончательно заменил метод map () на более эффективную (и более короткую) версию.Я знаю: версия, которая ищет разделы, все еще будет быстрее для больших массивов, но извините: я слишком ленив.
Если вы думаете, что это слишком раздутый, подумайте:
- Содержит компоновщик, который позволяет создавать Mapper с использованием синтаксиса varargs.Я бы сказал, что это необходимо для удобства использования
- Он содержит как один элемент, так и метод отображения коллекции
- Он неизменен и, следовательно, безопасен для потоков
Конечновсе эти функции могут быть легко удалены, но код будет менее полным, менее пригодным для использования или менее стабильным.