Java - Function "insert" for generic implements - java

public interface IGenericList<T> {
void insert(T element);
void println();
}
public class GenericList<T> implements IGenericList<T> {
private T param;
public GenericList(T rootValue) {
param = rootValue;
}
#Override
public void insert(T element) {
param = param + element; //error "Operator + cannot be applied to 'T', 'T'
}
#Override
public void println() {
System.out.println(param);
}
}
How can I implement that function? "insert"
I'm a beginner and that's all I'm given in the problem

I don't know for what you need IGenericList, because List interface is already generic and all implementations, but I don't know all business aspects.
For inserting some data you need proper data structure, the classic data structure for that is array. I wrote common logic for array field type in generic style.
public interface IGenericList<T> {
void insert(int index, T element);
void append(T element);
void println();
}
public static class GenericList<T> implements IGenericList<T> {
private T[] params;
public GenericList(T[] rootValue) {
this.params = rootValue;
}
#Override
public void insert(int index, T element) {
if(index > params.length) {
throw new IndexOutOfBoundsException();
}
params[index] = element;
}
#Override
public void append(T element) {
//find first null value or expand array and add value
}
#Override
public void println() {
System.out.println(Arrays.toString(params));
}
}

Related

How to Prevent Element<Integer> to become Element<Object>

For Syncing with some pice of Hardware, I have create a Datamodel containing a generic Class
DataField to store different Types of Objects in a HashMap.
HashMap myDictionary.
Now found out that if I store, a DataField into an DataField, it is possible to save an String inside the DataField.
Is there any way to prevent this from happening.
Here is my Code:
public class DataField<T> implements IDataField<T> {
//region Fields
private T _value;
private boolean _hasChanged;
private ChildObserable<T> _hasChangedObserverable;
//endregion
//region Methodes
public DataField(T val) throws IllegalValueException {
if(val.getClass() != _value.getClass()) throw new IllegalValueException();
_value =val;
_hasChanged=false;
_hasChangedObserverable=new ChildObserable<>();
}
public DataField(T val,Observer observer){
_value =val;
_hasChanged=false;
_hasChangedObserverable=new ChildObserable<>();
addChangeObserver(observer);
}
//region getters
#Override
public T getValue() {
return _value;
}
#Override
public boolean hasBeChanged() {
return _hasChanged;
}
//endregion
//region setters
#Override
public void setValue(T value) throws IllegalValueException {
if(value.getClass()!= _value.getClass()) throw new IllegalValueException();
if(value!=_value) {
_value = value;
_hasChanged=true;
_hasChangedObserverable.sendValue(_value);
}
}
#Override
public void clearChangedState() {
_hasChanged=false;
}
//endregion
//region observers
#Override
public void addChangeObserver(Observer observer) {
_hasChangedObserverable.addObserver(observer);
}
#Override
public void removeChangeObserver(Observer observer) {
_hasChangedObserverable.deleteObserver(observer);
}
//endregion
//endregion
}
and here is an Sample of Code what I mean:
DataField dataField = new DataField<Integer>(5);
dataField.setValue(true); // This can be prevented because of checking Class
DataField dataField = new DataField<String>(null);
dataField.setValue(5); // This can not be prevented because of NullPointer Exception
I found some Solutions like this How to keep generic type of nested generics with class tokens
but I don't like to overgive the Class two times
Another Idea of mine was to use a default(T) Function like C# to presetMy Value to an specific Type.
Thanks for help
I solved it using a seconde Construtor and a Class Field.
public DataField(T val) throws IllegalValueException {
if(val==null) throw new IllegalArgumentException("Class type couldn't be resolved from null");
_value =val;
_class=val.getClass();
_hasChanged=false;
_hasChangedObserverable=new ChildObserable<>();
}
public DataField(T val,Class<T> classType) throws IllegalValueException {
if(val!=null && val.getClass()!=classType) throw new IllegalArgumentException("Type of val and classType are Different");
_class=classType;
_value=val;
_hasChanged=false;
_hasChangedObserverable=new ChildObserable<>();
}
#Override
public void setValue(T value) throws IllegalValueException {
if(_class!= value.getClass()) throw new IllegalValueException();
if(value!=_value) {
_value = value;
_hasChanged=true;
_hasChangedObserverable.sendValue(_value);
}
}
Thanks for help

Not able to override method with generics

I have following methods defined in interface
public interface Stack<T> {
void method1(T element);
T method2();
}
Class Implementing this interface implements these methods as follows
private List<T> elements;
#Override
public void method1(T element) {
elements.add(element);
}
#Override
public T method2() {
return elements.remove(elements.size() - 1);
}
With this I get following error for method1: Method does not override method from super class, while method2 works fine.
Any idea what am I doing wrong?
This works perfectly fine:
import java.util.ArrayList;
import java.util.List;
public class Main {
interface MyStack<T> {
void push(T item);
T pop();
}
static class MyStackImpl<T> implements MyStack<T> {
private List<T> items = new ArrayList<T>();
#Override
public void push(T item) {
items.add(item);
}
#Override
public T pop() {
return items.remove(items.size() - 1);
}
}
public static void main(String[] args) {
MyStack<Integer> stack = new MyStackImpl<Integer>();
stack.push(42);
System.out.println(stack.pop());
}
}
You need to add type parameter to the interface and to the class too:
public interface Stack<T> { // here it is: <T>
void method1(T element);
T method2();
}
public class Impl<T> implements Stack<T> { // and here too
private List<T> elements;
#Override
public void method1(T element) {
elements.add(element);
}
#Override
public T method2() {
return elements.remove(elements.size() - 1);
}
}
You just need to specify the interface's generic type interface Stack<T>.
public interface Stack<T> {
void method1(T element);
T method2();
}
And you also need to define the generic type in you implementation class YourStack<T>
class YourStack<T> implements Stack<T>{
private List<T> elements;
#Override
public void method1(T element) {
elements.add(element);
}
#Override
public T method2() {
return elements.remove(elements.size() - 1);
}
}

Generic type use, in Java

I have a problem with the generic use I suppose,
Some code:
public class ObservableValue<T> extends Observable {
private T value;
public ObservableValue(T initial) {
setValue(initial);
}
public void setValue(T newValue) {
if (value != newValue) {
this.value = newValue;
setChanged();
notifyObservers(value);
}
}
}
public class SokobanGame implements Game, Observer {
protected final ArrayList<GameStatusBarElement<Integer>> windowElements;
public void nextLevel(Integer currentLevel){
this.windowElements.get(0).getElement().setValue(currentLevel);
for(GameStatusBarElement<Integer> element : windowElements)
element.update();
}
}
public class GameStatusBarElement<T> {
protected final ObservableValue<T> element;
public GameStatusBarElement(String elementText,
ObservableValue<T> observableValue) {
this.element = observableValue;
}
}
And that in the main implementation :
GameStatusBarElement<Integer> level = new GameStatusBarElement<Integer>("Level:", new ObservableValue<Integer>(1));
GameWindow gameWindow = new GameWindow("",
null, null, level);
}
So, the problem is: I cannot use setValue(currentLevel) (in SokobanGame) because of the currentLevel type, eclipse tell me to put something with the T type... But I instantiate the class of this.windowElements.get(0).getElement() with new GameStatusBarElement<Integer>("Level:", new ObservableValue<Integer>(1));, so I don't understand what's the problem ?
Everything seems fine, but I don't see the implementation of your getElement() method.
If your getElement() method is like this one:
public ObservableValue<T> getElement() {
return element;
}
it should compile just fine.

Defining types on object creation like HashMap<type here>

Very simple question, Im implementing a array enumeration class but cannot remember how to get the correct type back on the nextElement() method. The code is as follows...
public class ArrayEnumeration<Object> implements Enumeration<Object> {
private Object[] data;
private int n = 0;
public ArrayEnumeration(Object[] data) {
this.data = data;
}
#Override
public boolean hasMoreElements() {
return n < data.length;
}
#Override
public Object nextElement() {
n++;
return data[n - 1];
}
}
so object returned from the nextElement method should be the type that was defined when the class was created. I just cannot remember how to do it. So annoying!!!
Many thanks in advance.
Check out the source code of java.util.List for an example:
public interface List<E> extends Collection<E> {
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/List.java
Your methods then use the generic type:
public boolean add(E e);
public E get(int index);
All from the source of the java.util.List..
So in your case:
public class ArrayEnumeration<E> implements Enumeration<E> {
...
#Override
public E nextElement() {
n++;
return data[n - 1];
}
}
Use a type parameter:
public class ArrayEnumeration<T>
implements Enumeration<T>
{
private T[] data;
public ArrayEnumeration(T[] data)
{
this.data = data;
}
// ...
public T nextElement() {}
}
Also, you should consider using Iterator instead. But in any event, arrays implement Iterable, so why are you doing this?

How to handle generics inside a Java "annotation processor"?

I asked before for an example "annotation processor" that would generate a Proxy/Delegate for an interface, but got no answer, and did not find anything on the Internet, so I made my own.
So far it worked well, until I tried to use generics inside a super-interface. If I use generics in the annotated interface, it works fine (more by accident than by design). But if the annotated interface extends another interface that takes a generic type parameter, that parameter is not "bound" to the type that the annotated interface use when extending the super-interface. Example:
public interface TestFragment<E> {
void test(E dummy);
}
#CreateWrapper
public interface TestService extends TestFragment<String> {
double myOwnMethod();
}
This would generate:
// ...
public void test(final E dummy) {
wrapped.test(dummy);
}
// ...
instead of the correct:
// ...
public void test(final String dummy) {
wrapped.test(dummy);
}
// ...
The code that generates the parameters in the generated methods look like this:
int count = 0;
for (VariableElement param : method.getParameters()) {
if (count > 0) {
pw.print(", ");
}
count++;
pw.printf("final %s %s", param.asType().toString(),
param.getSimpleName().toString());
}
Is there a way to do this?
Have a look at http://docs.oracle.com/javase/6/docs/api/javax/lang/model/util/Types.html#asMemberOf%28javax.lang.model.type.DeclaredType,%20javax.lang.model.element.Element%29
Might be helpful. I used it to solve a very similar problem.
This can be quite simple if you follow Ryan Walls suggestion of using asMemberOf
ExecutableType methodType = (ExecutableType) typeUtil
.asMemberOf((DeclaredType) theAnnotatedClass.asType(), method);
int count = 0;
for (VariableElement param : method.getParameters()) {
if (count > 0) {
pw.print(", ");
}
TypeMirror actualParamType = methodType.getParameterTypes().get(count);
pw.printf("final %s %s", actualParamType.toString(),
param.getSimpleName().toString());
count++;
}
What you need is substitution, given a map of type variables to type arguments. In this case, E->String. Replace any E in any type with String
There is no such support in javax.lang.model.util.Types, you need to roll your own. Basically
void print(TypeMirror type, Map<TypeVariable,TypeMirror> substitution)
if(substitution.containsKey(type)) // type is a var, E
print( substitution.get(type) ); // String
else if(type instanceof DeclaredType) // e.g. List<E>
print( type.asElement().getSimpleName() ); // List
for(TypeMirror arg : type.getTypeArguments() ) // E
print(arg, substitution)
etc. something like that
Copy-paste of my original answer:
This seems to be a common question so, for those arriving from Google: there is hope.
The Dagger DI project is licensed under the Apache 2.0 License and contains some utility methods for working with types in an annotation processor.
In particular, the Util class can be viewed in full on GitHub (Util.java) and defines a method public static String typeToString(TypeMirror type). It uses a TypeVisitor and some recursive calls to build up a string representation of a type. Here is a snippet for reference:
public static void typeToString(final TypeMirror type, final StringBuilder result, final char innerClassSeparator)
{
type.accept(new SimpleTypeVisitor6<Void, Void>()
{
#Override
public Void visitDeclared(DeclaredType declaredType, Void v)
{
TypeElement typeElement = (TypeElement) declaredType.asElement();
rawTypeToString(result, typeElement, innerClassSeparator);
List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments();
if (!typeArguments.isEmpty())
{
result.append("<");
for (int i = 0; i < typeArguments.size(); i++)
{
if (i != 0)
{
result.append(", ");
}
// NOTE: Recursively resolve the types
typeToString(typeArguments.get(i), result, innerClassSeparator);
}
result.append(">");
}
return null;
}
#Override
public Void visitPrimitive(PrimitiveType primitiveType, Void v) { ... }
#Override
public Void visitArray(ArrayType arrayType, Void v) { ... }
#Override
public Void visitTypeVariable(TypeVariable typeVariable, Void v)
{
result.append(typeVariable.asElement().getSimpleName());
return null;
}
#Override
public Void visitError(ErrorType errorType, Void v) { ... }
#Override
protected Void defaultAction(TypeMirror typeMirror, Void v) { ... }
}, null);
}
I am busy with my own project which generates class extensions. The Dagger method works for complex situations, including generic inner classes. I have the following results:
My test class with field to extend:
public class AnnotationTest
{
...
public static class A
{
#MyAnnotation
private Set<B<Integer>> _bs;
}
public static class B<T>
{
private T _value;
}
}
Calling the Dagger method on the Element the processor provides for the _bs field:
accessor.type = DaggerUtils.typeToString(element.asType());
The generated source (custom, of course). Note the awesome nested generic types.
public java.util.Set<AnnotationTest.B<java.lang.Integer>> AnnotationTest.A.getBsGenerated()
{
return this._bs;
}
EDIT: adapting the concept to extract a TypeMirror of the first generic argument, null otherwise:
public static TypeMirror getGenericType(final TypeMirror type)
{
final TypeMirror[] result = { null };
type.accept(new SimpleTypeVisitor6<Void, Void>()
{
#Override
public Void visitDeclared(DeclaredType declaredType, Void v)
{
List<? extends TypeMirror> typeArguments = declaredType.getTypeArguments();
if (!typeArguments.isEmpty())
{
result[0] = typeArguments.get(0);
}
return null;
}
#Override
public Void visitPrimitive(PrimitiveType primitiveType, Void v)
{
return null;
}
#Override
public Void visitArray(ArrayType arrayType, Void v)
{
return null;
}
#Override
public Void visitTypeVariable(TypeVariable typeVariable, Void v)
{
return null;
}
#Override
public Void visitError(ErrorType errorType, Void v)
{
return null;
}
#Override
protected Void defaultAction(TypeMirror typeMirror, Void v)
{
throw new UnsupportedOperationException();
}
}, null);
return result[0];
}

Categories

Resources