ajxu2's blog

By ajxu2, history, 18 months ago, In English

Recently, I participated in Codeforces Round 873 (Div. 2). I was doing well, and in the last 5 minutes of the contest I solved problem D1, putting me at rank 200 and with CM performance. I was happy with myself until this happened:

I saw that I got TLE on test case 13 and quickly realized what happened. I chose to use Java in this round, and I had somehow fallen in another one of Java's traps. Now, I've decided to compile a comprehensive list of these pitfalls so no one can FST to them again. (Hopefully after you see this you'll be convinced to just use C++.)

1. Array sorting

Problem
Solution 1
Solution 2
Solution 3

2. String concatenation

Problem
Solution

3. Input/output

Problem
Solution

4. Comparing objects

Problem
Solution

5. Stacks

Problem
Solution

In conclusion, you should just use C++, because this is just too much stuff to remember. With C++, none of these are even issues.

If you have any more Java pitfalls, feel free to comment about them!

  • Vote: I like it
  • +130
  • Vote: I do not like it

| Write comment?
»
18 months ago, # |
  Vote: I like it +1 Vote: I do not like it

In conclusion, you should just use C++, because this is just too much stuff to remember. With C++, none of these are even issues.

Java is good enough to get you a decent rank. There are quite a number of red coders who use Java.

If you use a programming language without understanding what you are doing, then you will obviously run into this sort of problems. C++ has its pitfalls too.

For example in C++: for(int i = 0; i < n; i++) c = c + a; can potentially be much slower than for(int i = 0; i < n; i++) c += a;

where c and a are strings.

But then again, C++ is indeed faster than Java given that you use both languages correctly. But don't think that you can get away with slipshod understanding by using a faster programming language.

  • »
    »
    18 months ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    I agree that C++ has issues too, but in general, it has fewer issues, and the main ones (I/O, unordered_map) are really easy to fix. Therefore, it's less likely that you'll FST or get hacked with a C++ submission. On the other hand, it's really easy to fall into "black magic death traps" in Java that you didn't even know existed, especially considering most problems are made by C++ coders.

    Java is definitely good enough to get you a decent rank though (see SecondThread) and if you'd like to use Java then by all means go ahead.

»
18 months ago, # |
Rev. 5   Vote: I like it +1 Vote: I do not like it

Thanks for the helpful blog.


  • Set Long set = new HashSet<>();
  • long x = 5;
  • set.add(x);
  • out.println(set.contains(5));

  • Answer is false

  • Soln

  • out.println(set.contains(5L));
  • // true
  • Because of small stack size in java , many times DFS gives runtime error Is there any solution for it other than using BFS?

    for point 4 , instead of using equals , converting to int from integer than using == is much cleaner.

    • »
      »
      18 months ago, # ^ |
        Vote: I like it 0 Vote: I do not like it
    • »
      »
      16 months ago, # ^ |
        Vote: I like it 0 Vote: I do not like it

      Could you explain what this is and why that problem is occurring? I'm still a little confused about what the runtime error is, and why stack size has anything to do with this. This is probably due to my ignorance of Java docs, so any explanation would be appreciated!

      • »
        »
        »
        16 months ago, # ^ |
        Rev. 2   Vote: I like it +1 Vote: I do not like it

        Actually DFS uses recursion and recursion uses stack and there is a size limit of stack , so when the recursion goes deep the stack requires more memory , so by default it less and we can change it.

        e.g
        This Problem.
        This gives run time error and this passes after adjusting the stack size by adding this line

        new Thread(null, new Main(), "whatever", 1<<27).start();

        • »
          »
          »
          »
          16 months ago, # ^ |
            Vote: I like it +1 Vote: I do not like it

          oh, I see now thanks for the explanation. Your comment on longs was separate from your comment on stack size. I thought something about stack size was affecting the ==s operator on longs

    »
    18 months ago, # |
      Vote: I like it 0 Vote: I do not like it

    If the reference is compared, then shouldn't a==b have the same problem as c==d. why does one return true but the other return false? a, b, c, d are all Integers aren't they?

    • »
      »
      18 months ago, # ^ |
      Rev. 2   Vote: I like it +15 Vote: I do not like it

      there is some random java bullshit about numbers below 128 and numbers above iirc, maybe i remember the wrong border though

      • »
        »
        »
        18 months ago, # ^ |
          Vote: I like it 0 Vote: I do not like it

        Oh. Considering all these things, do ppl even like java? It seems very alien to me as a programming language lol.

      • »
        »
        »
        18 months ago, # ^ |
          Vote: I like it +8 Vote: I do not like it

        above 128 , for Integers == doesn't works

    • »
      »
      18 months ago, # ^ |
        Vote: I like it +13 Vote: I do not like it

      Java has something weird they do with small enough Integer values called auto-boxing.

      Auto-boxing is the idea of automatically converting a primitive (e.g. int) and its corresponding wrapper (e.g. Integer).

      Basically, $$$a$$$ and $$$b$$$ will both point to the same reference as they're small enough in absolute value ($$$-128 \le a,b \le 127$$$ if I remember correctly), whereas $$$c$$$ and $$$d$$$ are big enough that they'll be equal in value (c.equals(d) is true) but not in reference (c == d is false).

      • »
        »
        »
        18 months ago, # ^ |
          Vote: I like it +1 Vote: I do not like it

        I see. Im guessing they store all the number from [-128, 127] in memory and then create a reference to it when creating the variable?

    »
    18 months ago, # |
    Rev. 2   Vote: I like it 0 Vote: I do not like it

    as a non-java coder, I am asking myself... why TF doesn't Java offer an easy way to compare two numbers (using = or == or whatever) and instead you must use the ugly .equals()?

    • »
      »
      18 months ago, # ^ |
      Rev. 5   Vote: I like it 0 Vote: I do not like it

      Integer is a pointer in Java. The value type is int.

      == has been already defined on all pointers as comparing object id (kind of memory address), and Integer doesn't want to break this.

      If you use int (it's a more common case), you use ==. But however, you will be unable to assign null to the variable since it's not a pointer.

      int a = 1; // Ok
      Integer b = 1; // Ok, notice that it cast an `int` to a pointer, usually this is rejected by compilers of most languages, but Java provides a compiler feature called `autoboxing`, which will expand this line to `Integer b = Integer.valueOf(1);`
      int c = null; // Compile error, c is not a pointer
      Integer d = null; // Ok
      

      null is important for collections in Java, since the value may not be always present. For example.


      var map = ... // The keyword `var` in Java is something like `auto` in C++ Integer value = map.get("key"); if (value != null) { // If the value is found in the map // Do something } else { // If the value is not found in the map // Do something else }
    »
    18 months ago, # |
      Vote: I like it 0 Vote: I do not like it

    1.arrays.solution-3 , how does that work?

    »
    18 months ago, # |
      Vote: I like it 0 Vote: I do not like it

    For 5, you can use Dequeue also. It has the same complexity as of ArrayList.

    »
    18 months ago, # |
      Vote: I like it 0 Vote: I do not like it

    As you mentioned in the solution, all of the problems you mentioned with JJava can be bypassed effortlessly. Don't motivate people to leave Java. C++ also has issues like initializing randomly for primitive data type arrays. Java uses default values for them (0 for int[] and false for boolean[]).

    Also, Java does not provide Segmentation fault, which I like about Java.