How to set names of classes? - java

My code is:
public static <K, V> void initMapperJob( Job job,
Collection<WebPage.Field> fields, Class<K> outKeyClass, Class<V>
outValueClass, Class<? extends GoraMapper<String, WebPage, K, V>> mapperClass,
Class<? extends Partitioner<K, V>> partitionerClass, boolean reuseObjects)
throws ClassNotFoundException, IOException {
DataStore<String, WebPage> store = createWebStore(job.getConfiguration(), String.class, WebPage.class );
........
}
I change as like follows:
public static <K, V, P extends PersistentBase, F extends Fields> void initMapperJob(Job job,
Collection<F> fields,
Class<K> outKeyClass, Class<V> outValueClass,
Class<? extends GoraMapper<String, P, K, V>> mapperClass,
Class<? extends Partitioner<K, V>> partitionerClass, boolean reuseObjects)
throws ClassNotFoundException, IOException {
DataStore<String, P> store = createWebStore(job.getConfiguration(),
String.class, P.class );
....
}
My question is: how to set class of generics via java for the following line?
DataStore store = createWebStore(job.getConfiguration(),
String.class, P.class );
If I set as like ( P.class or P) , an error has occurred .
The following method is called.
public static <K, V extends Persistent> DataStore<K, V> createWebStore(Configuration conf,
Class<K> keyClass, Class<V> persistentClass){...}

You need to add a parameter of type Class<P> and use it (instead of P.class). you will then need to go to the site(s) where initMapperJob() and add that extra parameter to the call.
public static <K, V, P extends PersistentBase, F extends Fields>
void initMapperJob(Job job,
Collection<F> fields,
Class<K> outKeyClass, Class<V> outValueClass,
Class<? extends GoraMapper<String, P, K, V>> mapperClass,
Class<? extends Partitioner<K, V>> partitionerClass,
boolean reuseObjects,
Class<P> pClass) throws ClassNotFoundException, IOException {
DataStore<String, P> store = createWebStore(job.getConfiguration(),
String.class, pClass);
....
}

Related

Why is a subclass constructor undefined in its parent class?

I have a problem here that is probably very simple to solve, but unfortunately I'm still a bit stumped.
public final class ImmutableMap<K, V> extends AbstractReadableMap<K, V>
{
public ImmutableMap(Entry<K, V>[] entry)
{
super();
}
}
I have this class ImmutableMap<K, V> and its constructor.
public interface ReadableMap<K, V>
{
public abstract ImmutableMap<K, V> asImmutableMap();
}
I have this interface ReadableMap<K, V> and its abstract method asImmutableMap.
public abstract class AbstractReadableMap<K, V> implements ReadableMap<K, V>
{
protected Entry<K, V>[] entries;
public ImmutableMap<K, V> asImmutableMap()
{
return ImmutableMap(entries);
}
}
And finally I have this class AbstractReadableMap<K, V> where I'd like to implement the method asImmutableMap(). Unfortunately I get the error The method ImmutableMap(Entry<K,V>[]) is undefined for the type AbstractReadableMap<K,V>.
public class Launcher
{
public static void main(String[] args)
{
MutableMap<String, Integer> map = new MutableMap<String, Integer>();
putEntries(map);
printEntries(map);
ImmutableMap<String, Integer> immutableMap = asImmutableMap(map);
printEntries(immutableMap);
}
}
Same here: The method asImmutableMap(MutableMap<String,Integer>) is undefined for the type Launcher
Why is that and how can I fix it?
Thanks a lot in advance!

How can I do <T super V>?

I have a method looks like this.
public static <E extends Enum<E> & FieldEnum<E, V>, V>
void fieldValues(class<E> enumType,
Collection<? super V> fieldValues) {
for ( enumConstant : enumType.getEnumConstants()) {
fieldValues.add(enumConstant.fieldValue());
}
}
It might work.
List<Some> list = new ArrayList<>();
fieldValues(Some.class, list);
Now I want to change the method to return the given collection parameter(fieldValues). I did this.
public static <E extends Enum<E> & FieldEnum<E, V>, V, T super V>
Collection<T> fieldValues(Class<E> enumType,
Collection<T> fieldValues) {
for (E enumConstant : enumType.getEnumConstants()) {
fieldValues.add(enumConstant.fieldValue());
}
return fieldValues;
}
And the compiler complains.
com/github/.../lang/FieldEnums.java:[78,61] > expected
com/github/.../lang/FieldEnums.java:[78,62] illegal start of type
com/github/.../lang/FieldEnums.java:[78,69] '(' expected
How can I solve this? What is a proper way to return given collection so that I can do
List<Some> = fieldValues(Some.class, new ArrayList<Some>());
?
I found I just can
public static <E extends Enum<E> & FieldEnum<E, V>, V>
Collection<? super V> fieldValues(
Class<E> enumType, Collection<? super V> fieldValues) {
for (E enumConstant : enumType.getEnumConstants()) {
fieldValues.add(enumConstant.fieldValue());
}
return fieldValues;
}
Is there any other way better than this?
I'm answering for my own question so that anyone who has a similar problem can help themselves.
public static <E extends Enum<E> & FieldEnum<E, V>, V,
T extends Collection<? super V>>
T fieldValues(Class<E> enumType, T fieldValues) {
for (E enumConstant : enumType.getEnumConstants()) {
fieldValues.add(enumConstant.fieldValue());
}
return fieldValues;
}
Now I can do this.
List<Some> list = fieldValues(Some.class, new ArrayList<>());

Method signature with generic map extends object

Although this Piece of code is working, it still grinds my gears:
public static <K, V> Map<K, V> entityListToIdMap(List<? extends BaseEntity<K>> list, Class<K> keyClass) {
Map<K, V> map = new TreeMap<K, V>();
if(list != null){
for (BaseEntity<K> item : list) {
map.put(item.getId(), (V) item);
}
}
return map;
}
What i'm missing is, to tell the method signature, that V extends BaseEntity<K>. This may also lead to the unchecked warning which makes it necessary to cast the item in the value to V.
How can I tell V that it must extend BaseEntity<K>?
based on accepted answer from #Ori Lentz, the complete solution:
public static <K, V extends BaseEntity<K>> Map<K, V> entityListToIdMap(List<V> list, Class<K> keyClass) {
Map<K, V> map = new TreeMap<K, V>();
if (list != null) {
for (V item : list) {
map.put(item.getId(), item);
}
}
return map;
}
Simply define it when you define the generic type:
public static <K, V extends BaseEntity<K>> Map<K, V> entityListToIdMap(..) {

Can generic XmlAdapter be written

I know, that I can use Raw types to write XMLAdapter, but can I use generic types. I tried reading the API ( link ), but did not even notice a clue about this.
For example map:
I want to use, something like:
#XmlJavaTypeAdapter(GenericMapAdapter<String, Double>.class)//
private final HashMap<String, Double> depWageSum = //
new HashMap<String, Double>();
to get
<depWageSum>
<entry key="RI">289.001</entry>
<entry key="VT">499.817</entry>
<entry key="HI">41.824</entry>
...
<depWageSum>
And class itself would probably look something in the lines of:
#SuppressWarnings("serial") public class GenericMapAdapter<K, V> extends XmlAdapter<GenericMapAdapter.MapType<K, V>, Map<K, V>> {
public static class MapType<K, V> {
#XmlValue protected final List<MapTypeEntry<K, V>> entry = new ArrayList<MapTypeEntry<K, V>>();
public static class MapTypeEntry<K, V> {
#XmlAttribute protected K key;
#XmlValue protected V value;
private MapTypeEntry() {};
public static <K, V> MapTypeEntry<K, V> of(final K k, final V v) {
return new MapTypeEntry<K, V>() {{this.key = k; this.value = v;}};
} } }
#Override public Map<K, V> unmarshal(final GenericMapAdapter.MapType<K, V> v) throws Exception {
return new HashMap<K, V>() {{ for (GenericMapAdapter.MapType.MapTypeEntry<K, V> myEntryType : v.entry)
this.put(myEntryType.key, myEntryType.value);}};
}
#Override public MapType<K, V> marshal(final Map<K, V> v) throws Exception {
return new GenericMapAdapter.MapType<K, V>() {{for (K key : v.keySet())
this.entry.add(MapTypeEntry.of(key, v.get(key)));}};
} }
You will not be able to do this as described. The type parameters will not be retained by the class. However you could introduce some simple subclasses that could leverage the logic from your GenericMapAdapter:
public class StringDoubleMapAdapter extends GenericMapAdapter<String, Double> {
}
Then use the adapter sub class on the property:
#XmlJavaTypeAdapter(StringDoubleMapAdapter.class)//
private final HashMap<String, Double> depWageSum = //
new HashMap<String, Double>();
For more information on XmlAdapter see:
http://bdoughan.blogspot.com/2010/07/xmladapter-jaxbs-secret-weapon.html

Where's google-collection's LazyMap?

One of my favourites from apache commons-collections was the LazyMap which would use a Transformer to instantiate values on the fly when doing map.get(newKey); // Will not return null!.
Why doesn't google collections have the same?
Hey look! It does!
It's called new MapMaker().makeComputingMap(Function<? super K, ? extends V> computer)
Awesome.
Note that map maker is a factory - you can make one, set all the object reference types, expansion properties (and even object expiration time!), and then go about creating lots of computing maps (or other types) with one line calls.
e.g. like pretty much everything else about the google-collections library, it's really good - once you've figured out where 'it' is
since 10.0, guava have a new class CacheBuilder instead, and it's gwt-compatible.
These are the differences.
I suggest to write your own
public class LazyMap<K, V> extends ForwardingMap<K, V> {
final Function<? super K, ? extends V> factory;
final Map<K, V> delegate;
public static <K, V> LazyMap<K, V> lazyMap(final Map<K, V> map, final Supplier<? extends V> supplier) {
return new LazyMap<>(map, supplier);
}
public static <K, V> LazyMap<K, V> lazyMap(final Map<K, V> map, final Function<? super K, ? extends V> factory) {
return new LazyMap<>(map, factory);
}
private LazyMap(final Map<K, V> map, final Function<? super K, ? extends V> factory) {
this.factory = factory;
this.delegate = map;
}
private LazyMap(final Map<K, V> map, final Supplier<? extends V> supplier) {
this.factory = Functions.forSupplier(supplier);
this.delegate = map;
}
#Override
protected Map<K, V> delegate() {
return delegate;
}
#Override
public V get(final Object key) {
if (delegate().containsKey(key) == false) {
#SuppressWarnings("unchecked")
final K castKey = (K) key;
final V value = factory.apply(castKey);
delegate().put(castKey, value);
return value;
}
return delegate().get(key);
}
}

Categories

Resources