How to avoid unchecked cast warnings with Java Generics - java

Somehow my old question was closed, so I open a new one:
I am using Java Generics to implement a generic bidirectional Hash Map out of an SQL Query. It should be able to map any combination of String, Integer pairs back and forth. It should be used like this:
String sql = "SELECT string_val, int_val FROM map_table";
PickMap<String, Integer> pm1 = new PickMap<String, Integer>(sql);
String key1 = "seven";
Integer value1 = pm1.getLeft2Right(key1);
Integer key2 = 7;
String value2 = pm1.getRightToLeft(key2);
Of course it should be possible to create an pm (Integer, Integer) and so on...
My implementation of Pick Map looks like this (without the getter...):
public class PickMap<L, R> {
private final HashMap<L, R> left2Right = new HashMap<L, R>();
private final HashMap<R, L> right2Left = new HashMap<R, L>();
public PickMap(String sql) throws OException {
DTable d = new DTable(sql);
int colTypeL = d.t.getColType(1);
int colTypeR = d.t.getColType(2);
Extractor<L> extLeft = (Extractor<L>) getInstance(colTypeL);
Extractor<R> extRight = (Extractor<R>) getInstance(colTypeR);
int numRows = d.t.getNumRows();
for(int i=1;i<=numRows;i++) {
L leftVal = extLeft.extract(d, i);
R rightVal = extRight.extract(d, i);
this.left2Right.put(leftVal, rightVal);
this.right2Left.put(rightVal, leftVal);
}
}
private Extractor<?> getInstance(int type) {
if(type == 1)
return new IntExtractor();
else
return new StringExtractor();
}
}
interface Extractor<E> {
E extract(DTable source, int row);
}
class IntExtractor implements Extractor<Integer> {
#Override
public Integer extract(DTable source, int row) {
int value = 5;
return new Integer(value);
}
}
class StringExtractor implements Extractor<String> {
#Override
public String extract(DTable source, int row) {
String retVal = "hello";
return retVal;
}
}
I have no compiler errors and I'm pretty sure, that it will work this way. BUT I'm getting unchecked cast warnings on the "getInstance" methods Where I cast Extractor(E) to Extractor(L)...
How should I cast properly? Or what am I missing? Or should I just suppress those warnings?

You're getting warnings because what you're doing can't be proved to be safe. You're assuming that getInstance(colTypeL) will return an Extractor<L> - but that can't be verified at either compile-time or execution time.
You can use #SuppressWarnings("unchecked") as mentioned by others, but I would try to rethink the design somewhat.

You can use the following annotation to make the compiler not output those warnings:
#SuppressWarnings("unchecked")
See this related question which deals with the same issue. The answer there will explain everything you need to know.

If you are using the Spring Framework, you can use CastUtils:
import static org.springframework.data.util.CastUtils.cast;
obj.setString(cast(someObject));
String bob = cast(someObject);

Related

Dynamic return values with Mockito

One typically defines return values for a Mockito mock as follows:
MyClass myClass = Mockito.mock(MyClass.class);
when(myClass.myMethod()).thenReturn(0, 100, 200, ...);
Is there a way to this dynamically by supplying a seed and a function, e.g.:
when(mock.myMethod()).thenReturn(seed, previousVal -> previousVal + 100);
The easiest way may be to combine Mockitos Answer with lambdas, streams and iterators. The resulting code is
Iterator<Integer> values = Stream.iterate(0, n -> n + 100).iterator();
when(myClass.myMethod()).thenAnswer(i -> values.next());
The code can be made a little more efficient if you use an IntStream and a PrimitiveIterator.OfInt as the iterator type, but that is probably overkill for a unit test...
Yes, you can return an org.mockito.stubbing.Answer.
class AddingAnswer implements Answer {
int current = 0;
public Object answer(InvocationOnMock invocation) {
int result = current;
current += 100;
return result;
}
}
which you can then wire to your mock like this
Answer answer = new AddingAnswer();
when(myClass.myMethod()).then(answer);
Or in the generic version you want
class DynamicAnswer<T> implements Answer {
T currentValue;
UnaryOperator<T> adjustment;
public DynamicAnswer(T seed, UnaryOperator<T> ad) {
currentValue = seed;
adjustment = ad;
}
public Object answer(InvocationOnMock invocation) {
T result = currentValue;
currentValue = adjustment.apply(currentValue);
return result;
}
}
You can use thenAnswer() as described on mockitos web site.
when(mock.myMethod()).thenAnswer(new Answer<Integer>(){
private final int seed=100;
private int previousVal=0;
public Integer answer(InvocationOnMock invocation) throws Throwable {
int currentVal= previousVal;
previousVal += seed;
return currentVal;
}
});
but usually this requirement arises from a flawed testing approach:
Each method in a unittest class should verify a single expectation on the code under test. Therefore there should be no need for such "dynamic" test value generation.

How to use ENUM to return random strings out of three?

With the use of below code, I am finding out which datacenter I am in and it is working fine..
public enum DatacenterEnum {
DEV, DC1, DC2, DC3;
private static DatacenterEnum compareLocation() {
String ourhost = getHostName();
for (DatacenterEnum dc : values()) {
String namepart = "." + dc.name().toLowerCase() + ".";
if (ourhost.indexOf(namepart) >= 0) {
return dc;
}
}
return null;// I don't want to do this now.
}
}
But it might be possible that it is not able to find any datacenter, so currently I am returning null.
Is there any direct way or a single line command by which I can return randomly either DC1 or DC2 or DC3 in the ENUM instead of returning null?
I know one way is to make a list of string and then randomnly select any integer between 0 to 2 inclusive and then find the string. But it is too much code, actually it's not but just trying to see is there any other way we can do this?
Any simple and direct way which I can use in the ENUM directly?
Here's the one line:
return DataCenterEnum.values()[new Random().nextInt(3) + 1)];
For those who require tighter control on their code, here's a safer version, which does not depend on the order of the enum instances:
return new DataCenterEnum[]{DC1, DC2, DC3}[new Random().nextInt(3)];
Here is a generic solution that will work for any enumeration.
Convenience method for single exclusion:
public static <E extends Enum<E>> E getRandom(Class<E> aEnum, E exclude) {
return getRandom(aEnum, Collections.singletonList(exclude));
}
Generic method that works with one or more exclusions:
public static <E extends Enum<E>> E getRandom(Class<E> aEnum, List<E> exclude){
//Convert set of enums into a list
List<E> enums = new ArrayList<E>(EnumSet.allOf(aEnum));
//Remove items from the list that you want to exclude
enums.removeAll(exclude);
int size = enums.size();
if(size != 0){
//Get random enum
int randomIndex = new Random().nextInt(size);
return enums.get(randomIndex);
} else {
throw new IllegalArgumentException("Empty Enumeration after excludes");
}
}
For your example you could call
EnumUtil.getRandom(DatacenterEnum.class, DatacenterEnum.DEV);
You could use the values() method, which returns an array. Then just use Math.random() to return a random instance.
Here is an example:
public static void main (String[] args) {
String[] arr = {"DEV","DC1","DC2","DC3"}; //returned by Enum.values(), you get the idea
String randElement = arr[(int) ((Math.random() * 3) +1)];
System.out.println(randElement);
}
Basically it boils down to generating a random number between 1 and n :)

Is there a way to achieve implicit type cast or conversion in java

I wanted to create a method that takes an enum and uses it directly in an computation
private static int getEntries(List<Integer> vector, Sign sign)
{
//assert isPrimitiveTypeCompliant(vector) : "Vector has null components!";
int entries = 0;
for (Integer entry : vector)
if (entry * sign > 0) // does not compile
entries++;
return entries;
}
I thought sth. like that was possible, since I assumed System.out.println(Object) does implicit type conversion, too. Which it doesn't, it uses following approach:
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
Question
So is it possible to achieve this in java? Or is this reserved to C++ and overloading of operators? What are the common workarounds? Utility/Adapter classes that do the work?
Btw, I eventually ended up with this approach
private enum Sign
{
POSITIVE(+1), NEGATIVE(-1);
private int sign;
private Sign(int sign)
{
this.sign = sign;
}
public int process(int n)
{
if (n * sign > 0)
{
return n;
}
return 0;
}
}
private static int getEntries(List<Integer> vector, Sign sign)
{
//assert isPrimitiveTypeCompliant(vector) : "Vector has null components";
int entries = 0;
for (Integer entry : vector)
entries += sign.process(entry);
return entries;
}
Yes, it is possible to achieve it. In fact, you did in the second piece of code.
Java doesn't have operator overloading or implicit conversions (beyond numerical conversions and "widening" type casts). So, there is no way of allowing syntax like entry * sign (except the one you used).
What do you mean workarounds? This is not a problem. It is a language design decision. And you already arrived successfully to the appropriate Java idiom.
why not just use the int value of the sign
if (entry * sign.value > 0)
enum Sign
public final int value;
I think for this case it would work better for you to use final static variables.
public final class Sign {
public final static int POSITIVE = 1;
public final static int NEGATIVE = -1;
private Sign() {
}
}
Then you can use Sign.POSITIVE and Sign.NEGATIVE for the operations you want.

Java enum alternative to how I did this?

Teaching myself Java by coding a MIDI handling program. One thing the program needs to be able to do is convert back and forth between MIDI note numbers and their corresponding compact string representations. I looked at using an enum setup, but due to naming constraints you can't do something like
c-1, c#-1, ... g9;
because of the sharps and negatives (yes, I'm following the convention that makes you end up with a negative octave :P).
It seemed clunky to have to make a conversion between what's allowed and what I want.
CNEG1("c-1"),
CSNEG1("c#-1"),
DNEG1("d-1"),
...
G9("g9");
So I came up with the static imports scheme below, and it works fine. However, I want to learn more about how to use enums, and I have a hunch that they might actually be somehow better suited to the task - if only I understood the ins and outs better. So that's my question: can anyone come up with an elegant way to provide the same functionality using an enum scheme? Moreover, would there be a strong argument for doing so?
public abstract class MethodsAndConstants {
public static final String TONICS[] = {"c","c#","d","d#","e","f","f#","g","g#","a","a#","b"};
static final NoteMap notemap = new NoteMap();
static class NoteMap{
static String map[] = new String[128];
NoteMap() {
for (int i = 0; i < 128; i++){
int octave = i/12 - 1;
String tonic = MethodsAndConstants.TONICS[i%12];
map[i] = tonic + octave;
}
}
}
public static int convert_midi_note(String name){
return indexOf(NoteMap.map, name);
}
public static String convert_midi_note(int note_num){
return NoteMap.map[note_num];
}
public static int indexOf(String[] a, String item){
return java.util.Arrays.asList(a).indexOf(item);
}
}
EDIT ------------------------------------------
After heavy consideration I think in this particular situation enums might be overkill after all. I might end up just using this code down here, same sort of static import approach but no longer even requiring anything like the NoteMap business up above.
note_num -> name conversions are really straightforward, and the name -> note_num stuff is just good ol' string-parsing fun.
public abstract class MethodsAndConstants {
public static final String[] TONICS = {"c","c#","d","d#","e","f","f#","g","g#","a","a#","b"};
static String convert(int i) {
String tonic = MethodsAndConstants.TONICS[i%12];
int octave = (i / 12) - 1;
return tonic + octave;
}
static int convert(String s) {
int tonic = java.util.Arrays.asList(MethodsAndConstants.TONICS).indexOf(s.substring(0,1));
if (s.contains("#")) tonic += 1;
int octave = Integer.parseInt(s.substring(s.length()-1));
if (s.contains("-")) octave -= 2; // case octave = -1
int note_num = ((octave + 1) * 12) + tonic;
return note_num;
}
}
You could use an enum to represent the pitch, but I might try encapsulating a Pitch in a class
public class Pitch {
private final int octave;
private final Note note;
public enum Note {
C("C",4), CSHARP("C#/Db",5), DFLAT("C#/Db",5), //and so on
private final String thePitch;
private final int midiAdjust;
private Note(final String thePitch, final int midiAdjust) {
this.thePitch = thePitch;
this.midiAdjust = midiAdjust;
}
String getThePitch() {
return thePitch;
}
int getMidiAdjust() {
return midiAdjust;
}
}
public Pitch(Note note, int octave) {
this.note = note;
this.octave = octave;
}
public int getMidiNumber(){
return 12*octave + note.getMidiAdjust();
}
}
This would account for the fact that the note (C, C#, D, D#, E...) is going to be one of a repeating set, but you could have all kinds of octaves, in this case handled by an int. It would greatly reduce the size of your enum.
EDIT: I added a few lines in here as an idea. You could pass a second parameter into the constructor of the enum to allow you to return a MIDI number representing the pitch. In this one I assumed that the lowest number represented by MIDI is an A, but I may be wrong on that. Also the 12*octave is intended to add a whole octave of pitches for each increment. You will probably have to adjust this slightly, as I see you are using that one weird notation.
Something like that:
public enum Note {
CNEG1("c-1"), CSNEG1("c#-1"), DNEG1("d-1");
private final String tonicOctave;
private Note(final String tonicOctave) {
this.tonicOctave = tonicOctave;
}
public String getTonicOctave() {
return this.tonicOctave;
}
public static Note fromTonicOctave(final String val) {
for (final Note note: Note.values()) {
if (note.getTonicOctave().equals(val)) {
return note;
}
}
return null;
}
}
Note, you can have as many parameters as you need in your enum, so if you need to separate tonic and octave, you can.

"Generic" solution for primitive array?

I have classes that for processing primitive array input: CharArrayExtractor for char[], ByteArrayExtractor for byte[], IntegerArrayExtractor for int[], ...
public void CharArrayExtractor {
public List<Record> extract(char[] source) {
List<Record> records = new ArrayList<Record>();
int recordStartFlagPos = -1;
int recordEndFlagPos = -1;
for (int i = 0; i < source.length; i++) {
if (source[i] == RECORD_START_FLAG) {
recordStartFlagPos = i;
} else if (source[i] == RECORD_END_FLAG) {
recordEndFlagPos = i;
}
if (recordStartFlagPos != -1 && recordEndFlagPos != -1) {
Record newRecord = makeRecord(source, recordStartFlagPos,
recordEndFlagPos);
records.add(newRecord);
recordStartFlagPos = -1;
recordEngFlagPos = -1;
}
}
}
}
public void ByteArrayExtractor {
public List<Record> extract(byte[] source) {
// filter and extract data from the array.
}
}
public void IntegerArrayExtractor {
public List<Record> extract(int[] source) {
// filter and extract data from the array.
}
}
The problem here is that the algorithm for extracting the data is the same, only the types of input are different. Everytime the algorithm changes, I have to change all of the extractor classes.
Is there a way to make extractor classes more "generics"?
Best regards.
EDIT: It seems that every suggestion so far is to use autoboxing to archive generic. But the number of elements of the array is often large, so I avoid using autoboxing.
I added more specific implementation of how the data is being extracted. Hope it will clarify something.
New Idea
Or a different approach is wrapping the primitive arrays and covering them with the methods you use for your algorithm.
public PrimitiveArrayWrapper {
private byte[] byteArray = null;
private int[] intArray = null;
...
public PrimitiveArrayWrapper(byte[] byteArray) {
this.byteArray = byteArray;
}
// other constructors
public String extractFoo1(String pattern) {
if(byteArray != null) {
// do action on byteArray
} else if(....)
...
}
}
public class AlgorithmExtractor {
public List<Record> do(PrimitiveArrayWrapper wrapper) {
String s= wrapper.extractFoo1("abcd");
...
}
}
This mainly depends if you have a lot of methods to call which you would have to cover. but at least you must not edit the algorithm more over the way how to access the primitive array. Furthermor you would also be able to use a different object inside the wrapper.
Old Idea
Either use generics or what i also think about is to have three methods which convert the primitive types into value types.
public void Extractor {
public List<Record> extract(byte[] data) {
InternalExtractor<Byte> ie = new InternalExtractor<Byte>();
return ie.internalExtract(ArrayUtils.toObject(data));
}
public List<Record> extract(int[] data) {
...
}
}
public void InternalExtractor<T> {
private List<Record> internalExtract(T[] data) {
// do the extraction
}
}
ArrayUtils is a helper class from commons lang from Apache.
I'm not sure how your filter will work as it will not know anything about the type the array contains.
Using reflection you can possibly do what you want but you will loose compile time type safety.
The java.lang.reflect.Array class provides functions for manipulating an array without knowing its type.
The Array.get() function will return the value at the requested index of the array and if it is a primitive wrap it in its corresponding Object type. The downside is you have to change your method signature to accept Object instead of specific array types which means the compiler can no longer check the input parameters for you.
Your code would become:
public class ArrayExtractor {
public List<Record> extract(Object array) {
// filter and extract data from the array.
int length = Array.getLength(array);
for (int index = 0; index < length; index++) {
Object value = Array.get(array, index);
// somehow filter using value here
}
}
}
Personally I would prefer having type safety over using reflection even if it is a little more verbose.
interface Source
int length();
int get(int index);
extract(final byte[] source)
extract( new Source(){
int length(){ return source.length; }
int get(int i){ return source[i]; }
} );
// common algorithm
extract(Source source)
for(int i=0; i<source.lenth(); i++)
int data = source.get(i);
...
Instead of passing each type, pass the class of the type as the below:
public List<Record> extract(Class srcClass) {
if (int[].class.equals(srcClass) {
// filter and extract data from the int[] array.
}
else if (..) // do same for other types
}
public void Extractor<T> {
public List<Record> extract(T[] source) {
// filter and extract data from the array.
}
}
http://download.oracle.com/javase/tutorial/extra/generics/methods.html
You could do something like this.
public class ArrayExtractor<T>
{
public List<T> extract (T[] source)
{
// filter and extract data from the array.
}
}
You would have a generic Extractor class and your implementation would be the same.
You cant use Javas generics because of primitive type source, your best bet is to try some java reflection api to analyze the incoming source and invoke the extractors on your own.
I think is is possible to do create a method like this:
public List<Record> extract(List<Number> source) {
// filter and extract data from the array.
}
And use Arrays.asList(yourPrimaryArrayType), to make it compatible.
After my tests and the comment of Sean Patrick Floyd, you will be able to do this by create once some helper methods, for converting primitive arrays to lists:
public static void main(String[] args)
{
int[] i = {1,2,3};
System.out.println(extract(asPrimitiveList(i)));
}
public static List<Object> extract(List<Number> source) {
List<Object> l = new ArrayList<Object>();
l.add(0);
for (Number n : source)
{
// I know this line is rubbish :D
l.set(0, ((Number) l.get(0)).doubleValue() + n.doubleValue());
}
return l;
}
private static List<Number> asPrimitiveList(int[] ia)
{
List<Number> l = new ArrayList<Number>(ia.length);
for (int i = 0; i < ia.length; ++i)
{
l.add(ia[i]);
}
return l;
}
private static List<Number> asPrimitiveList(byte[] ia)
{
List<Number> l = new ArrayList<Number>(ia.length);
for (int i = 0; i < ia.length; ++i)
{
l.add(ia[i]);
}
return l;
}
private static List<Number> asPrimitiveList(char[] ia)
{
List<Number> l = new ArrayList<Number>(ia.length);
for (int i = 0; i < ia.length; ++i)
{
l.add(ia[i]);
}
return l;
}
No, it is never possible.
For example take a look at documentation of ArrayUtils.copyOf(byte[] original, int newLength). And there exists other methods for remaining primitives. This is kind of same behavior (literally) you wanted. If it was possible similar code should exists somewhere else.
Additionally we can discuss more about how generic works, but it would be another issue, i guess.
Depends on what you're trying to achieve. But maybe you can work with primitive wrappers instead? Then you could write generic Extractor<? extends Number> (here Number is the abstract class extended by all primitive wrappers).
Yes, you should be able to use generics:
interface Extractor<T, R> {
public List<R> extract(T source);
}
class BaseExtractor<T> implements Extractor<T, Record>
{
public List<Record> extract(T source)
{
//do your thing
}
}
Here, you would have to assume that T is a primitive array, as you cannot use primitives in generic definitions.
Or else, you could use the wrapper Objects and do it this way:
interface Extractor<T, R> {
public List<R> extract(T[] source);
}
class BaseExtractor<T> implements Extractor<T, Record>
{
public List<Record> extract(T[] source)
{
//do your thing
}
}
In this case, your generic T can be Byte, Integer, etc.

Categories

Resources