for not supporting user-defined operators. Operator overloading improves readability, so its absence can make Java code less readable, especially for classes representing mathematical objects, such as complex numbers and matrices. Java has only one non-numerical use of an operator: + and += for string concatenation. However, this is implemented by the compiler, which generates code to create StringBuilder instances. It is impossible to create user-defined operator overloads. Compound value types Java lacks compound value types, such as structs in C, bundles of data that are manipulated directly instead of indirectly via references. Value types can sometimes be faster and smaller than classes with references. For example, Java's HashMap is implemented as an array of references to HashMap.Entry objects, which in turn contain references to key and value objects. Looking something up requires inefficient double dereferencing. If Entry were a value type, the array could store key-value pairs directly, eliminating the first indirection, increasing locality of reference and reducing memory use and heap fragmentation. Further, if Java supported generic primitive types, keys and values could be stored in the array directly, removing both levels of indirection. Large arrays Java has been criticized for not supporting arrays of 231 (about 2.1 billion) or more elements. This is a limitation of the language; the Java Language Specification, Section 10.4, states that: Arrays must be indexed by int values... An attempt to access an array component with a long index value results in a compile-time error. Supporting large arrays would also require changes to the JVM. This limitation manifests itself in areas such as collections being limited to 2 billion elements and the inability to memory map continuous file segments larger than 2 GB. Java also lacks multidimensional arrays (contiguously allocated single blocks of memory accessed by a single indirection), which limits performance for scientific and technical computing. There is no efficient way to initialize arrays in Java. When declaring an array, the JVM compiles it to bytecodes with instructions that set its elements one by one at run time. Because Java methods cannot be bigger than 64KB, arrays of even modest sizes with values assigned directly in the code will throw the message "Error: code too large" on compilation. Integration of primitives and arrays Arrays and primitives are somewhat special and need to be treated differently from classes. This has been criticized because it requires many variants of functions when creating general-purpose libraries.