I am developing a security program I am facing a big problem about generics.
Consider the following code :
abstract class Dictionary{
List<Entity> list;
public Dictionary(List<Entity> list){
this.list = list; // Error
}
}
Entity is a user defined interface and It has two implementing classes:
interface Entity{
...
}
class BinaryEntity implements Entity{
}
class ListEntity implements Entity{
}
The problem raises in use of inheritance.I have a concrete class called binary dictionary which extends abstract class dictionary.it contains a list of binary entity the problem is when i want to pass the list to super class constructor there is a error I know the following statement is wrong :
ArrayList<BinaryEntity> a;
List<Entity> b = a;\\erro
I have tried upper and lower bounding but still in trouble help please.
Sorry for the long question. Thanks in advance
You'll need to make Dictionary generic as well, e.g.:
abstract class Dictionary<E extends Entity> {
List<E> list;
public Dictionary(List<E> list){
this.list = list;
}
}
class BinaryDictionary extends Dictionary<BinaryEntity> {
public BinaryDictionary(List<BinaryEntity> list) {
super(list);
}
// ... custom methods
}
Related
I finished some exercise but I wanted to optimize it a little bit.
I have two classes name "U1" and "U2", both extend the same abstract class called "Rocket" and I have two functions called "loadU1" and "loadU2" that returns ArrayList (U1 or U2) and i wanted to optimize it to one function without success. I tried the generic type, but I cant figure out how should I know which type to return or cast to. Does it possible?
Note: I didn't share some code that I have tried because I got no idea where should I start even (JAVA Newbie).
This is the strcture of the classes:
public class U1 extends Rocket {}
public class U2 extend Rocket {}
abstract class Rocket implements SpaceShip {}
These are the current functions:
public ArrayList<U1> loadU1(ArrayList<Item> items) {
ArrayList<U1> u1Rockets = new ArrayList<>();
return u1Rockets;
}
public ArrayList<U2> loadU2(ArrayList<Item> items) {
ArrayList<U2> u2Rockets = new ArrayList<>();
return u2Rockets;
}
Maybe you are looking for something like this:
public <T extends Rocket> List<T> load(List<Item> items) {
List<T> rockets = new ArrayList<>();
return rockets;
}
I recently picked up MapStruct, and I really like the way it works. Since I'm new to MapStruct, I apologize in advance if this question is silly or makes little sense.
Due to server version, I'm bound to Java 6.
I have 3 types of entities, A, B, and C, as well as their DTO counterparts.
public class A{
//...
}
public class B extends A{
//...
}
public class C extends A{
//...
}
public class ADto{
//...
}
public class BDto extends ADto{
//...
}
public class CDto extends ADto{
//...
}
My mapper defines:
public abstract ADto mapAToADto(A source);
public abstract A mapADtoToA(ADto source);
public abstract BDto mapBToBDto(B source);
public abstract B mapBDtoToB(BDto source);
public abstract CDto mapCToCDto(C source);
public abstract C mapCDtoToC(CDto source);
Which works fine for now.
In my application, I work with List<A> and List<ADto> that contains both subtypes.
My current implementation was to implement my own mapping method that iterates over source list and checks types with instanceof , then calls matching mapping method listed above.
Current implementation:
public <T extends ADto, S extends A> List<T> toList(List<S> source) {
if (source == null) {
return null;
}
List<T> list = new ArrayList<T>();
for (S entity : source) {
if (entity instanceof B) {
list.add((T) mapBToBDto((B) entity));
} else if (entity instanceof C) {
list.add((T) mapCToCDto((C) entity));
} else {
list.add((T) mapADtoToA((A) entity));
}
}
return list;
};
I was wondering if there is a way to direct MapStruct to figure it out automatically. Am I missing something?
Edit:
My optimistic approach was with:
#IterableMapping(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULL)
public abstract <T extends ADto, S extends A> List<T> listAToADto(List<S> source);
Which results in:
Can't generate mapping method for a generic type variable target
Thank you
Your implementation is correct. MapStruct is an Annotation Processor that generates code during compilation. We don't generate any reflection checks (All the types that implement and interface or extend a class are not known during compilation). Therefore your approach to the problem is correct.
I want to create object like belows :
private MyHashTable<AVLtree<TreeData>, TreeData> hashTable = new MyHashTable<>();
AVLtree and TreeData is what I defined, not java built in class.
But, I have no idea how to define MyHashTable class using generic.
What I can think about is
public class MyHashTable<S<T>,T> but it doesn't work.
You can declare like this
public class MyObject<T> {
}
public class MyHashTable<S extends MyObject<T>, T> {
}
In this case you can use
public class MyHashTable<S extends AVLTree<T>, T> {
}
Hope this help.
I have a generic class "SimpleList" (excerpt):
public abstract class SimpleList<T> {
protected List<T> list;
public SimpleList(List<T> list) {
this.list = list;
}
}
And another class "TrackList" that extends it (excerpt):
public class TrackList extends SimpleList {
public TrackList(List<XmlTrack> list) {
super(list);
}
}
In "TrackList" I specify that the list is to hold objects of type "XmlTrack". It seems though, like it's not possible to get an object from that list and access its methods. For example, this won't work:
list.get(0).someMethodSpecificToXmlTrack()
I don't understand why this doesn't work? Isn't the list in "SimpleList" set to only hold "XmlTrack"s?
You need to define it as
public class TrackList extends SimpleList<XmlTrack> {
public TrackList(List<XmlTrack> list) {
super(list);
}
}
Because SimpleList is generic, but you did not specify a type argument when you extended it.
May be you need
public class TrackList extends SimpleList<XmlTrack>
I've noticed something funny Java does (or at least Netbeans) when I use classes implementing ArrayList and changing the generics type of the elements. I basically created an abstract class that extends ArrayList and some subclasses that are supposed to work with String objects (so something like ArrayList<String>). One of the things I did to try to achieve that was this:
public abstract class A extends ArrayList {
...
}
#Override
public abstract class B extends A {
public Iterator<String> iterator() {
return super.iterator();
}
}
Another one was this:
public abstract class A extends ArrayList {
...
}
public abstract class B<String> extends A {
#Override
public Iterator<String> iterator() {
return super.iterator();
}
}
The first one overrides successfully the iterator() method assigning a String value to it. The other one somehow cancels out the type casting. The funny thing is that none of them works when it comes to for loops. This receives type Object instead of String.
for (String s : B) {
...
}
Do you have any idea why this happens and how can I fix it without implementing my own iterator?
Not sure what you are trying to do but if I understand correctly you want a class that extends ArrayList and has a Generic type of String... Perhaps you are looking for this:
public abstract class A<T> extends ArrayList<T> {
...
}
public abstract class B extends A<String> {
...
}
Then in your code, this:
B myList = ...;
for ( String s : myList ) {
...
}
Will work just fine. Though I think you could come up with a much better solution. Do you have more specifics about your problem?
Use composition instead of Inheritance
public class A implements Iterable<String>{
List<String> myList = new ArrayList<String>();
//do operations on myList
public Iterator<String> iterator() {
return myList.iterator();
}
}
If you extend generic class you should care about generics. I mean that your declaration should look like
public abstract class A extends ArrayList<String> {
...
}
if you want to use strings or
public abstract class <T> A extends ArrayList<T> {
...
}
if you want your class to be generic.
In both cases you do not have to override iterator() method: you can invoke its from super class and it will return you "good" iterator. Your declaration is equivalent to
public abstract class A extends ArrayList<Object> {
...
}
This is the reason for "strange" behavior.
BTW may I ask you why are you extending ArrayList? It really sounds strange.
OMG this is terrible:
public abstract class B<String> extends A {
#Override
public Iterator<String> iterator() {
return super.iterator();
}
}
String is not the class String, rather, you are declaring a new type variable called String (like T) that shadows the class String