How to convert one generic list to another in java - java

I am trying to convert one generic list of enums to another generic list type but always getting the following compile error:
Is not applicable for the arguments
private static <T extends Enum<T>> List<T> enumListFromEnumList(List<Object> sourceEnumsList, Class<T> classObject) {
List<T> enums = new ArrayList<T>();
if(sourceEnumsList != null) {
for(Object enumObject : sourceEnumsList) {
if (enumObject instanceof Enum)
enums.add(Enum.valueOf(classObject, enumObject.toString().toUpperCase()));
}
}
return enums;
}
Even I tried this:
private static <T extends Enum<T>> List<T> enumListFromEnumList(List<T> sourceEnumsList, Class<T> classObject) {
List<T> enums = new ArrayList<T>();
if(sourceEnumsList != null) {
for(T enumObject : sourceEnumsList) {
enums.add(Enum.valueOf(classObject, enumObject.toString().toUpperCase()));
}
}
return enums;
}
This is how I'm consuming the function:
adapterInfo.setResponseTypeList( enumListFromEnumList(info.getResponseTypeList(), CAPInfo.ResponseType.class));
Updates:
It works when I convert to this:
private static <S extends Enum<S>, T> List<S> enumListFromEnumList(List<T> sourceEnumsList, Class<S> classObject) {
List<S> enums = new ArrayList<S>();
if(sourceEnumsList != null) {
for(T enumObject : sourceEnumsList) {
enums.add(Enum.valueOf(classObject, enumObject.toString().toUpperCase()));
}
}
return enums;
}
So now the question is how to translate "<S extends Enum<S>, T> List<S>" part ( I mean how it works)

Here is what you are looking for (I think) :
enum EnumA {
FIRST,
SECOND,
THIRD
}
enum EnumB {
FIRST,
SECOND,
THIRD
}
private static <A extends Enum<A>, B extends Enum<B>> List<B> enumListFromEnumList(List<A> sourceEnumsList, Class<B> classObject) {
List<B> enums = new ArrayList<B>();
if (sourceEnumsList != null) {
for (A enumObject : sourceEnumsList) {
enums.add(Enum.valueOf(classObject, enumObject.toString().toUpperCase()));
}
}
return enums;
}
public static void main(String[] args) {
List<EnumA> listA = new ArrayList<EnumA>();
listA.add(EnumA.FIRST);
listA.add(EnumA.THIRD);
List<EnumB> listB = enumListFromEnumList(listA, EnumB.class);
System.out.println(listB);
}

Related

Caching using Supplier Java 8

This method, as I know, memorizes (caches) the value of supplier that passed as the parameter. As I understand It behaves like singleton pattern. Can anyone explain how it works?
public static <T> Supplier<T> memoize(final Supplier<? extends T> valueSupplier)
{
final List<T> memoryList= new ArrayList<>();
return () -> {
if (memoryList.isEmpty()) {
memoryList.add(valueSupplier.get());
}
return memoryList.get(0);
};
}
Usage like this:
Supplier<SomeClass> cachedValue = memoize(() -> someClassObject.getSomeValueToBeCached());
cachedValue.get().doMethod();
Ok, so let's rewrite the code in small steps towards more old-style, verbose Java.
Maybe that makes it simpler to understand.
First step: get rid of the lambda:
public static <T> Supplier<T> memoize(final Supplier<? extends T> valueSupplier)
{
final List<T> memoryList= new ArrayList<>();
return new Supplier<T>() {
#Override
public T get() {
if (memoryList.isEmpty()) {
memoryList.add(valueSupplier.get());
}
return memoryList.get(0);
}
};
}
Next step: extract the anonymous inner class into a standalone class.
While the anonymous class had access to the local variables of its containing method (memoryList), a "normal" class has not, so we're moving the list into the caching supplier.
class CachingSupplier<T> implements Supplier<T> {
final List<T> memoryList= new ArrayList<>();
private Supplier<T> originalSupplier;
public CachingSupplier(Supplier<T> originalSupplier) {
this.originalSupplier = originalSupplier;
}
#Override
public T get() {
if (memoryList.isEmpty()) {
memoryList.add(originalSupplier.get());
}
return memoryList.get(0);
}
}
public static <T> Supplier<T> memoize(final Supplier<? extends T> valueSupplier) {
return new CachingSupplier<>(valueSupplier);
}
Finally, let's replace the ArrayList by a simple reference.
class CachingSupplier<T> implements Supplier<T> {
private T cachedValue;
private Supplier<T> originalSupplier;
public CachingSupplier(Supplier<T> originalSupplier) {
this.originalSupplier = originalSupplier;
}
#Override
public T get() {
if (cachedValue == null) {
cachedValue = originalSupplier.get();
}
return cachedValue;
}
}
public static <T> Supplier<T> memoize(final Supplier<? extends T> valueSupplier) {
return new CachingSupplier<>(valueSupplier);
}
Maybe that's easier to understand. If you are still unclear about something, just ask in a comment
and I'll try to explain it.
How about this?
public static <T> Supplier<T> memoize(final Supplier<? extends T> factory) {
final List<T> cache = new ArrayList<>();
return () -> {
// v--- check the value is cached?
if (cache.isEmpty()) {
// v--- return the value created by factory
cache.add(factory.get());
// ^--- adding the value into the cache
}
return cache.get(0);
// ^--- return the cached value
};
}
Usage
Supplier<String> factory = ()-> new String("foo");
assert factory.get() == factory.get(); // return false;
assert memoize(factory).get() == memoize(factory).get(); //return false;
// v--- storing the memoized factory for using as further
Supplier<String> memoized = memoize(original);
assert memoized.get() == memoized.get(); // return true.
// ^--- they are the same.

Using generics for a class how can I convert the values from one type to another?

I built a simple document store, there are entities that have fields of different types, I have a Float, Int and String type. The entity contains an array list of values, if someone updates the schema of the entity I would like to be able to try to convert the values to the new type.
public interface FieldType<T> {
ArrayList<T> values;
}
public class FloatField implements FieldType<Float> {
}
public class StringField implements FieldType<String> {
}
I have thought about using a abstract class with methods as below
public abstract class Field<T> implements FieldType<T> {
abstract public <T> castFromString(String value);
abstract public <T> castFromFloat(Float value);
abstract public <T> castFromInt(Int value);
}
public class FloatField extends Field<Float> {
#override
public <Float> castFromString(String value){
Float castValue = null;
try {
castValue = Float.parseFloat(value);
} catch(Exception e){
}
return castValue;
}
}
I did not really like this solution as I would have to add a new abstract method each time I added an extra type to the system.
Any ideas how I could implement this better?
Maybe you could use the Function<T, R> interface?
public abstract class Field<T> implements FieldType<T> {
...
public <F> T convert(F value, Function<F, T> converter) {
try {
return converter.apply(value);
} catch(Exception e) {
return null;
}
}
...
}
And then specify the converter using a lambda expression or a method reference:
field.convert("1234", BigDecimal::new); //with a method reference
field.convert("1234", s -> new BigDecimal(s)) //with a lambda
This would replace all of your convertXXX methods by one since the return type is inferred from the passed Function.
EDIT:
If you want automatic converting, you would of course have to hard-code these since you wouldn't want to write conversion methods for all 4240 classes in the Java API. This gets messy, though. Maybe something like this in a static helper class or in FieldType itself?
public class WhereverYouWantThis {
private static HashMap<Class<?>, HashMap<Class<?>, Function<?, ?>>> converters = new HashMap<>();
static {
putConverter(String.class, Float.class, Float::parseFloat);
}
private static <T, R> void putConverter(Class<T> t, Class<R> r, Function<T, R> func) {
HashMap<Class<?>, Function<?, ?>> map = converters.get(t);
if(map == null) converters.put(t, map = new HashMap<>());
map.put(r, func);
}
public static <T, R> Function<T, R> getConverter(Class<T> t, Class<R> r) {
HashMap<Class<?>, Function<?, ?>> map = converters.get(t);
if(map == null) return null;
#SuppressWarnings("unchecked")
Function<T, R> func = (Function<T, R>) map.get(r);
return func;
}
public static <T, R> R convert(T o, Class<R> to) {
#SuppressWarnings("unchecked")
Function<T, R> func = (Function<T, R>) getConverter(o.getClass(), to);
return func == null ? null : func.apply(o);
}
}
I don't think you need generics for this. Instead, just try to create a Float from the input String and return null if there be a problem:
public Float castFromString(String value) {
Float castValue = null;
try {
castValue = Float.parseFloat(value);
} catch(Exception e){
// log here
}
return castValue;
}
The reason I don't think generics are needed is that the types involved in the conversion are named/known in your helper methods.

How to remove 'unchecked' warning from my method?

I have following code
private static class ParcelableParser<T> {
private ArrayList<T> parse(List<Parcelable> parcelables) {
ArrayList<T> parsedData = new ArrayList<T>();
for(Parcelable parcelable : parcelables) {
parsedData.add((T) parcelable);
}
return parsedData;
}
}
It is called as follows
ParcelableParser<SomeClass> cellParser = new ParcelableParser<SomeClass>();
cellParser.parse(bundle.getParcelableArrayList("some String"));
It gives warning Type safety: Unchecked cast from Parcelable to T.
No matter what I do, I always have some nasty compilation error.
I have read about PECS rule, but I am not able to apply it here.
sample solution (does not compile)
private static class ParcelableParser<T extends Parcelable> {
private ArrayList<T> parse(List<T> parcelables) {
ArrayList<T> parsedData = new ArrayList<T>();
for(T parcelable : parcelables) {
parsedData.add((T) parcelable);
}
return parsedData;
}
}
Using it as
return new ParcelableParser<SomeClass>()
.parse(bundle.getParcelableArrayList("SomeString"));
prodces
The method parse(List<SomeClass>) in the type MyClass.ParcelableParser<SomeClass> is not applicable for the arguments (ArrayList<Parcelable>)
As you know parcelable is of type T why don't you use T instead. Try this:
public static class ParcelableParser<T> {
private ArrayList<T> parse(List<T> parcelables) {
ArrayList<T> parsedData = new ArrayList<T>();
for(T parcelable : parcelables) {
parsedData.add(parcelable);
}
return parsedData;
}
}

java - How to get the type of the parameter from a parameterized argument

I'm having troubles trying to find a solution, if any, to this:
public class Generics {
Map<Class<? extends SomeObject1>, SomeObject2>> map;
map = new HashMap<Class<? extends SomeObject1>, SomeObject2>>();
public static <E extends SomeObject1> SomeObject2 get(Class<E> c) {
if (map.containsKey(c))
return map.get(c);
else {
SomeObject2 o = new SomeObject2();
map.put(c, o);
return o;
}
}
}
...
//somewhere
public <T extends SomeObject1> void aMethod(AnInterestedClass<T> list) {
// How to get the value from the map
// knowing that the key is of type T?
Generics.get();
}
Ideas?
Because of type erasure, you can only do this by passing a Class object to aMethod. See this related thread.

Need some slight help on this generic Java

I'm trying to make this code as generic as possible, but im stuck right on the last part. This is where my code is called:
List<Integer> NewList = map(OriginalList, new IFunction<Integer>(){
public <T extends Number> int execute(T anInt){
return anInt.intValue() + 1;
}
});
then I have the method map:
public static <T> List<Integer> map(List<T> c, IFunction<T> f) {
List<Integer> TempList = new ArrayList<Integer>();
for (T o : c){
TempList.add(f.execute(o));
}
return TempList;
}
and the interface IFunction:
public interface IFunction<T> {
public <T extends Number> int execute(T o);
}
my error is in Map() where it says TempList.add(f.execute(o)); i am trying to declare the TempList to be of type T and the execute method to return an incremented number in Type T.
Every time i fix one part of the code i seem to have ruined another part. Ideally all parameters would be generic and there would be no 'Integer' anywhere except where i call my code
You need to constrain your parameter in the map() method:
public static <T extends Number> List<Integer> map(List<T> c, IFunction<T> f) {
...
Otherwise f.execute() will complain that the type of the argument can be anything, and it expects a Number.
Try this:
IFunction.java
public interface IFunction <T extends Number> {
T execute(T obj);
}
Main.java
public class Main {
public static void main(String[] args) {
List<Integer> originalList = new ArrayList<Integer>();
List<Integer> newList = map(originalList, new IFunction<Integer>(){
public Integer execute(Integer anInt){
return anInt.intValue() + 1;
}
});
}
public static <T extends Number> List<T> map(List<T> c, IFunction<T> f) {
List<T> tempList = new ArrayList<T>();
for (T o : c){
tempList.add(f.execute(o));
}
return tempList;
}
}
You should try a different Generic Setup:
public interface IFunction<T extends Number> {
public int execute(T o);
}
List<Integer> NewList = map(OriginalList, new IFunction<Integer>(){
public int execute(Integer anInt){
return anInt.intValue() + 1;
}
});
public static <T extends Number> List<Integer> map(List<? extends T> c, IFunction<T> f) {
List<Integer> tempList = new ArrayList<Integer>();
for (T o : c){
tempList.add(f.execute(o));
}
return tempList;
}
This is as close as I could get to removing Integer (changing variable names to start lower case):
public class Main
{
public static void main(String[] args)
{
List<Integer> originalList = new ArrayList<Integer>();
originalList.add(1);
originalList.add(2);
originalList.add(3);
originalList.add(4);
List<Integer> newList = map(originalList, new IFunction<Integer>()
{
public <T extends Number> T execute(T aNumber)
{
Integer result = aNumber.intValue() + 1;
return (T) result;
}
});
System.out.println(newList);
}
public static <T extends Number> List<T> map(List<T> c, IFunction<T> f)
{
List<T> tempList = new ArrayList<T>();
for (T number : c)
{
tempList.add(f.execute(number));
}
return tempList;
}
}
and
public interface IFunction<T> {
public <T extends Number> T execute(T o);
}
Still got one inside the implementation of execute().

Categories