4

I'm in university and struggling with this task. I tried for weeks, but I just can't understand this task. I have get a "OK", but I can only edit and add code between those two comments.

static void insertEvil() {
    var intList = new ArrayList<Integer>();
    // Change starts here
    intList.add(42);
    // Change ends here
    if (intList.get(0).equals("Hello World")) {
        System.out.println("Ok");
    } else {
        System.out.println("Failure");
    }
}

I tried to "transform" an "Hello World" String into an Hashcode using hashcode(), but it is not working.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • have you tried using intList.add("Hello World".hashCode()); – The Shmoo Apr 20 '23 at 13:14
  • 1
    I fail to see how your code has anything to do with hashCode generation. Please provide more information. And be specific. *`but I can only edit and add code between those two commands`* What commands? – WJS Apr 20 '23 at 13:15
  • 1
    `a.equals(b)` will *always* return `false` if `a` is an instance of `Integer` and `b` is an instance of `String`. Moreover, how do you expect us to help you with your problem if you do not even state the problem in the question? – Thomas Behr Apr 20 '23 at 13:15
  • What's the name and topic of the module you're studying? If it's about generics and type erasure in Java, it might be because it's possible to add the wrong type to lists in Java, although it's never recommended (the method name insertEvil hints that you should be trying to do it in an evil way). – Ian Newson Apr 20 '23 at 13:16
  • Just do `((List) intList).add(0, "Hello World")` (NVM, that is not going to work given the return type of `get(0)`) – Mark Rotteveel Apr 20 '23 at 13:17
  • Sorry i try to be more accurate now. My module is called "software" and my task is it to get a true from the if statement without changing the if statement. I can only write things between //change starts here and //Change ends here. – Student23452345 Apr 20 '23 at 13:19
  • do you know exactly how equals works? – Stultuske Apr 20 '23 at 13:22
  • Are you allowed to do anything there? Including ending the current method and defining another method? – Mark Rotteveel Apr 20 '23 at 13:23
  • @Stultuske yes and it triggered me a lot because my teacher gave us this task. Until now one has get this correct. – Student23452345 Apr 20 '23 at 13:25
  • @MarkRotteveel no Im not allowed to do this. – Student23452345 Apr 20 '23 at 13:26
  • @maloomeister Compiler won't allow it. – WJS Apr 20 '23 at 13:36
  • Are you certain you have posted the correct, original code, sans any of your modifications? – WJS Apr 20 '23 at 13:36
  • Probably not what you want but: `System.out.println("Ok"); System.exit(0);` in between the comments :) – 001 Apr 20 '23 at 13:36
  • @WJS unfortunately this is copy paste and we asked him if this is a joke:) – Student23452345 Apr 20 '23 at 13:37
  • @WJS yeah, got that too. – maloomeister Apr 20 '23 at 13:39
  • @001 wow thats smart, i think its better than nothing – Student23452345 Apr 20 '23 at 13:43
  • Nice [nerd snipper](https://xkcd.com/356/). I tried to fake `intList` as `class intList {static String get(int i) {return "Hello World";}}` (possible in Java 17) but no success - class declaration compiles fine but does not shade variable. May be it will inspire someone else. I agree with others it's mainly the puzzle to educate generics rather than expect some unconventional hack. Anyway it's hard to see any solution 100% covering your requirements. Put solution here please if you find out or get told, could be as self-answer. I am sure many people are interested in it as well. – Tomáš Záluský Apr 21 '23 at 06:40
  • Hi, did you reach out to your teacher and ask for a solution? I've spent some time thinking about it, and I don't think it's possible. – Ian Newson May 05 '23 at 19:08

2 Answers2

3

Since the method is named insertEvil, the point of this exercise is probably to teach you that it is possible to insert the "wrong" type of object to a ArrayList<T>, and that generics are not actually enforced at runtime. See: type erasure.

In this case, you need to insert a String into a ArrayList<Integer>.

One way to do it is to cast it to a raw type:

((ArrayList)intList).add("Hello World");

However, this doesn't actually cause your code to print "OK", because the call to intList.get would attempt to cast the string you inserted back to an Integer, because intList is declared to be an ArrayList<Integer>. The cast will fail at runtime.

To get this to work, you need intList to be a ArrayList or ArrayList<String>, so the call to get wouldn't try to cast the string to Integer.

If you are only allowed to change the code between the two comments, the only ways I can think of are dirty tricks like declaring a new method. You can still declare a new method by just changing the lines between the two comments.

For example, if the code between the two comments are replaced with:

helper(intList);
}
static void helper(ArrayList intList) {
intList.add("Hello World");

Then it becomes:

static void insertEvil() {
    var intList = new ArrayList<Integer>();
    // Change starts here
    helper(intList);
}
static void helper(ArrayList intList) {
    intList.add("Hello World");
    // Change ends here
    if (intList.get(0).equals("Hello World")) {
        System.out.println("Ok");
    } else {
        System.out.println("Failure");
    }
}

The idea is to pass intList to another method, to change what intList means in the get call. In the above code, intList in the get call now refers to the method parameter, instead of the variable declared in insertEvil.

That said, I think it is highly likely that the intended solution is just ((ArrayList)intList).add("Hello World");. Whoever designed this might not have considered that get would cast the element back to an Integer. (I nearly missed it too!)

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • The OP said you can't use a new method. – WJS Apr 20 '23 at 14:00
  • @WJS yeah, which is why I said that the intended solution might just be casting to a raw type and adding the element. I also suspect that OP meant “no declaring methods *outside of the two comments*” After all, the original post is apparently a direct copy-paste, and it doesn’t mention anything about declaring new methods. It could just be that OP is not aware of a way to declare a new method by only changing the code inside the two comments, and so said what they said. – Sweeper Apr 20 '23 at 14:17
  • The OP said they have been working on this for weeks. So I also just checked. April 1st was on a Saturday. :) – WJS Apr 20 '23 at 14:19
  • Yes you are right, i meant no declaring methods outside outside of the two comments. I think until now this is the best solution. Thanks ! – Student23452345 Apr 20 '23 at 14:21
1

I have get a "OK", but I can only edit and add code between those two comments.

Well, this works but I'm not certain if it was the desired solution. But there are no warnings or compiler errors.

static void insertEvil() {
   var intList = new ArrayList<Integer>();
   // Change starts here
   if(intList instanceof List) {
       System.out.println("Ok");
       return;
   }
   // Change ends here
   if (intList.get(0).equals("Hello World")) {
       System.out.println("Ok");
   } else {
       System.out.println("Failure");
   }
}

But for that matter you could do anything, print OK and exit. So there must be more to this.

WJS
  • 36,363
  • 4
  • 24
  • 39