-1

When trying to compare keys when implementing merge sort on a linked list I found that Java seems to hide generic types of fields from outside the class, and you have to either cast a variable to the generic type (even when it is of the generic type itself), or make an instance of the class that uses generics and then access the field from there

public class LinkedList<Item extends Comparable<Item>> {
    private Node<Item> head;
    
    public static class Node<Item> {
        public Item key;
        public Node<Item> next;
    }

    public LinkedList() {
        head = null;
    }

    public LinkedList<Item> merge(LinkedList a, LinkedList b) {
        if (a == null || a.head == null) {
            return b;
        } else if (b == null || b.head == null) {
            return a;
        }
        LinkedList<Item> x = null;
        Item keyA = (Item) a.head.key;
        Item keyB = (Item) b.head.key;
        Node<Item> node = a.head;
        Item works = node.key;
        Item doesNotWork = (a.head).key;
        ...

In the code snippet above, keyA and keyB must have their values casted to the generic type Item. The node object of type Node can be used to reference its key which is of type Item, but trying to initialize doesNotWork results in the error "java: incompatible types: java.lang.Object cannot be converted to Item", even though it referenes the Node head object, and then the Item key object within it (with brackets too). Changing the access modifiers of the class or its fields makes no difference. Can someone explain why Java can't access generic types within classes despite being able to do so for concrete types, and if I can reference a generic type from outside a class without casting or making an instance of the class with the generic type?

No, this is not the same as the question about raw types because the answers to that do not tell me how I can directly reference a field of the static generic class. I know this is a terrible way to use generics, but the code given (apart from at the end) was from a lab in my algorithms class, I don't choose the code they give us. It's also not really fair that I didn't lookup raw types since I never really knew what they were. I can't edit the code template they gave us, please let me ask how I can do what I need to for this assignment instead of being a code snob.

wh152
  • 1
  • 3
  • 1
    Have you tried `merge(LinkedList a, LinkedList b)`? It looks to me like that will solve your problem quite normally. – Louis Wasserman Feb 23 '23 at 02:53
  • As an aside, are you sure you want `merge` to take two parameters, rather than taking one parameter and merging it with the `LinkedList` that it was called on? As written, it looks like it ignores the list it was called on (at least in the part of the method included in the question). So, to merge lists `a` and `b` you need to call `a.merge(a, b)` or `b.merge(a, b)` or `new LinkedList<>().merge(a, b)` instead of `a.merge(b)`. – Tim Moore Feb 23 '23 at 10:14
  • You are using [raw types](https://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it) as your method arguments, which basically "turns off generics". – Joachim Sauer Feb 23 '23 at 10:42
  • @matt the thread that apparently answer my question doesn't, it just says to not use raw types. I appreciate that using raw types is bad, but I have to use this code template that I was given for my lab assignment, it was written by maths professors who have only a reasonable understanding of programming – wh152 Feb 23 '23 at 15:22
  • @matt the original answer just says to not use raw types. I have to use raw types for the lab since that is the code I've been given, I wanted to know how I could workaround this. You never really explained why it's apparently a dupe, you just said it's "absolutely" been asked before. Yes the guy who gave the answer read the thread, but I wasn't talking about them – wh152 Feb 24 '23 at 11:39
  • Do you know where you were using raw types? The answer fixes that problem. It is also a duplicate question, because you are using raw types which causes your problem. – matt Feb 24 '23 at 16:27

1 Answers1

1

From the logic of your list it is implied that both lists beeing merged must be of the same Item type - then you can type them and this will also avoid all the unnecessary casting.

public LinkedList<Item> merge(LinkedList<Item> a, LinkedList<Item> b)
SDekov
  • 9,276
  • 1
  • 20
  • 50