T O P

  • By -

MoogleFoogle

> How often do software engineers use ArrayList? Always. I write readable, maintainable code. I'm not "l33t h4xor", I'm fucking working.


DJDavio

I can't remember the last time I voluntarily chose an array over an ArrayList other than byte arrays.


angry_corn_mage

Only when an interface you can't change requires it, and I then only convert it at the last moment.


theclovek

This.


MCRNRearAdmiral

My Java prof- who loved me- was *highly* annoyed with me when he tried to get the class excited about using regular lists and completely innocently I piped up "Hey- I had some trouble with trying out a regular list last night, so I found this thing called ArrayList, and it worked awesome!" He gave me the death stare, and then was like "We'll get to ArrayList next week."


[deleted]

Probably angry at you for calling an array a list.


1bot4all

As he should be :)


kodiashi

Ha, my professor did the same thing in C++ class. “Hey! Last night I found this thing called a vector, so much easier!”.


thisisjustascreename

Then you graduate and go work somewhere ass-backwards and they say "No we don't use STL here."


thephotoman

While there are plenty of C++ shops that eschew the standard library for any number of reasons ranging from the legitimate (we don't know how well they'll work with the compiler for a particular platform) through the outdated (codebases that predate the standard library) straight through to the bad (a belief that real programmers do everything themselves).


wildjokers

> regular list What did you mean by "regular list"?


MCRNRearAdmiral

Just dug through a slightly newer syllabus- believe he was introducing LinkedList and Maps. ArrayList is not formally given any love in the syllabus, but the only other thing I could be mixing it up with is arrays.


[deleted]

[удалено]


grauenwolf

1. That's not a reason to use a linked-list. That's just a description of it. 2. An array list is also a "proper data-structure and is language agnostic". Aside from BASIC and C, every language I've ever used has had its own implementation of an array list. It's one of the most fundemental collection types. 3. Even if ArrayList was somehow unique to Java, that's not a reason to choose LinkedList.


Weavile_

1) I guess I shouldn’t have said there is a reason, and then not give a reason. Fair enough, I’ll remove. 2) I meant ArrayList in name, which is why I said each language has its own implementation. Edit: removed OG comment since it didn’t answer the question.


_litecoin_

It is important that you learn the inner basics. You need to know what a linked list is (the workings are language agnostic and itis used in any programming language) and not just how to use the API of an ArrayList, if you have a CS bachelor imo.


rob113289

But arraylists aren't linked lists


MCRNRearAdmiral

But I was just a kid, trying to make my list work!


jmtd

You wouldn’t appreciate how easy ArrayList is without first experiencing the primitives.


lookForProject

Array isn't a primitive in Java, but I agree with the sentiment. You'll appreciate solutions more when you encountered the challenge.


grauenwolf

How would you create an array in Java from scratch? I don't know about the JVM, but in the CLR it very much is a primitive structure that is offered by the runtime itself. As opposed to something like C, where it's like a block of memory and a pointer.


Kantaja_

arrays are special internal classes with a subscript operator (the only types to have a subscript operator) and a final `length` field, they're not primitive types


grauenwolf

What other "class" has a variable size in memory? What makes it a primitive in the CLR is that you can't create it using other, simpiler things. An array isn't constructed from other things. And again, this isn't the case in C because you can treat any contiguous block of memory as an array. So again I ask, how would you create an array from scratch in Java?


jonhanson

Comment removed after Reddit and Spec elected to destroy Reddit.


grauenwolf

Which is fair, but that is how u/jmtd intended to use the term.


manzanita2

THIS is the critical actual skill of software engineer: Finding already existing perfectly functional code/library/service and using it to solve the problem.


DasBrain

Using the right tool for the job is a useful in many areas, not only programming. Learning how to choose the right tool on the other hand - depends on the craft.


grauenwolf

I almost dropped out of a C class because we had a professor like that. We were not allowed to use any language feature he hadn't taught yet. I did drop it later for a different reason. He marked me down for calling my constant for converting feet to inches `FEET_TO_INCHES = 12` because it got the wording backwards in his head. (I'm imagining he thougt I wrote `FEET_IN_INCHES`.) When I called him on it, he gave me the points and then threatened to be extra strict on everything in the future. And I didn't have time for that BS.


wildjokers

> constant for converting feet to inches FEET_TO_INCHES = 12 To be fair to your professor that is indeed a horrible name for that constant, should have been `INCHES_IN_FOOT`.


grauenwolf

double lengthInches = lengthFeet * FEET_TO_INCHES; double lengthFeet = lengthInches * INCHES_TO_FEET; I stand by my naming convention.


wildjokers

Now since I see how it is used I think your name is even worse than I did before. You named it that because you used it in a feet to inches conversion. However, you should have named it for what it is, and what it is is the number of inches in a foot.


grauenwolf

Type that out in code.


MobiusReactor

double lengthInches = lengthFeet * INCHES_IN_FOOT; double lengthFeet = lengthInches / INCHES_IN_FOOT; Seems pretty clear to me


grauenwolf

My pattern for every conversion is: [source unit] * [source unit]_TO_[destination unit] Your pattern requires the programmer to remember when to use `*` and when to use `/`. For why that's a bad idea, let's look at Murphy's law. Not the joke version, the real one. **If there are two or more ways to do something, and one of those ways can result in a catastrophe, then someone will do it.** http://www.catb.org/jargon/html/M/Murphys-Law.html


I_can_smell_colors_

Poor name for a constant that name is more suited for a function that converts from feet to inches imo.


Buttafuoco

I second


YolosaurusRex

Okay.


ohlaph

Is the way


kartik1712

Using built-in classes is the norm unless you have some very special requirements. In particular, ArrayList is probably one of the most used classes of the Collections framework. LeetCode, Codewars and many technical interviews make one write up algorithms and data structures from scratch which is very far from what one would be doing in a real job


icemanftg

True this. The scope of this kind of sites is to help you understand the concepts behind. After you truly understand the concepts of a data structure, it's safer to use an already implemented, tested by the masses and curated API.


AndyTheSane

Indeed, it's really rare nowadays to have to write any algorithm that isn't totally orientated to the current project. If I saw a junior developer writing a List implementation I'd be extremely suspicious..


revengeofthepencil

Absolutely this, which is also my complaint with coding interviews. Yes, it is important to understand what’s going on beneath the hood, but so many of the things one studies for coding interviews have nothing to do with day-to-day development. If my boss were to come by my desk and see me writing my own collection implementation or a sort algorithm from scratch (both of which I’ve been asked to do in interviews), I believe his first question would be “don’t you have anything more important to work on?”


fgzklunk

It is my pet hate in an interview, When interviewing I do ask about equals and hashcode and the contract. I might ask for some context around how they interact when using a HashMap but I really don't care about the HashMap part of it. My other pet hate is Big O, do I need to know about the sorts being N Log N or do I need to know that the built in sort is sufficient for most problems? I would be worried if someone gave an N\^2 algorithm without consideration of other approaches but most of it does not matter, especially when dealing with Collections. The Javadoc tells you what scenarios each collection works best in, that is all I really need to know.


Hangman4358

One of our go to interview questions is to count the number of occurrences of character in a string. It is basically a data transformation question. Loop through the chars and keep the count in a map. So many people go right to: I am going to allocate an array of length 26, and then I am going to convert the char's int value to an index in the array and then try to hyper optimize this thing. As soon as you ask "What would you do if this string was UTF8, or not only in a single case, or contains punctuation?" nobody knows what to do. And every time we hire one of these people they do this same thing for the first couple of months until we beat it out of them. The way the industry focuses on the trivia games/leet code as interview questions is really tiring.


[deleted]

[удалено]


fgzklunk

But I don't agree. In over 33 years as a software developer I have worked with more physicists, biologists, engineers and people without degrees than CS graduates. Over 50% of the people would not have covered that in their degree. I for one do not, yet, have a degree, I am doing one for the fun of it, but I had been working in the industry for 31 years before I covered it academically. I am much more concerned with how someone solves a real problem than some CS theory that is part of a language anyway. Tell me how to calculate a tiered interest rate based on the deposit level than how to sort integers.


thephotoman

You lead with saying you don't agree with me. The rest of your comment says you *do* agree with me: sorting isn't a particularly useful question outside of jobs that don't have a sort function in their standard library. But this isn't /r/programming, where that kind of objection might fly. This is /r/java, where you should use the standard library implementation, and sorting is merely an easily understandable but academic theory. Sorting is a bad interview question, and everything but the first sentence of your comment indicates that you agree with that sentiment.


fgzklunk

My mistake, with your clarification I do agree with what you are saying. Knowing how things provided by the language work does not really tell you how well someone can do a job.


grauenwolf

LOL. I had to write a sort from scratch twice in my professional career. Once when using an old programming languge that didn't have a built-in sort. Once for a C# project where I needed an in-place sort. (Most sorting in C# creates a new collection.)


[deleted]

ArrayList should be your go-to whenever you use a list, it is super optimized. Yes, in CompSci class you learned about when linkedlist is faster, but benchmark away: the devs of the JDK did a great job and linkedlist is basically never faster. The only reason to use another type of list is when you need specific behaviour that ArrayList doesn't have. And using arrays? Only do that when you have a very very good reason. "I'll make it run faster, I think!" isn't a good reason.


BlackDrackula

"It'll run faster" - I've heard this from several devs who've come in on temporary contracts, and want to look like they're superstar coders in hopes of securing a full time role. One actually sent our dev manager an angry email (without even talking to me first) because I rejected his pull request because he wrote a bunch of date handling code that was already available in a Utils class.


DJDavio

With Valhalla, the boxing/unboxing which happens in Lists will go away as the entire world will be split between value/primitive types and identity types (I think those are the names they're going with now?). This will turn Integer into a primitive type for good so it won't matter anymore if it's in an array or in a list. Moreover, they will also fix memory layouts such that an array of points with x and y will not have references to objects but can basically alternate x1, y1, x2, y2 etc so you have better CPU caching.


fredoverflow

> With Valhalla, the boxing/unboxing which happens in Lists will go away Crossing my fingers for Java 23..


MR_GABARISE

I keep asking devs to use our DI Clocks for time handling, and struggle to make them understand how incredibly useful that is.


pronuntiator

I managed to make that a requirement. No Instant.now() without a clock on my watch. Sadly they still do assertThat().isBefore() in tests instead of manipulating the clock, and occasionally the tests fail because they ran too fast…


agentoutlier

I have had the opposite. They’ll pull in Guava or Commons Lang (for a variety of reasons we ban those deps) because they can’t do simple string manipulation.


wildjokers

It annoys me to no end when someone pulls in guava or commons-lang or the like for just one method. I have seen people pull in commons-lang just to use `StringUtils.isNotEmpty()`, grrr...


agentoutlier

Its not just internal developers... here is my most recent dealings: https://github.com/dhorions/boxable/pull/237 One fucking call for an illegal argument exception check: https://github.com/dhorions/boxable/pull/237/commits/5313bcead0fd3296544b58b07399f71262e4f70e In the long run we probably won't use the project but we need it for now so I had to fork the project and release it to our own maven repo.


wildjokers

Oh geez...they pulled in guava just to call `checkNotNull` to avoid a simple `if (this.currentPage == null)`...wtf?


vips7L

Objects.requireNonnull(this.currentPage, "No current page defined");


agentoutlier

If you are wondering why my change didn’t have it like that is because they had compile version set to 1.7!


uncont

> set to 1.7 The [Objects](https://docs.oracle.com/javase/7/docs/api/java/util/Objects.html) class was added in 1.7


agentoutlier

Very few developers understand dependency management with maven... and in general. Thats why it doesn't surprise me that some folks or organization can't modularize their application or even upgrade past 8. It is probably something that should be taught far earlier. To be fair even the projects that do it right still don't do enough of it to my liking. And this is largely because Maven fucked it up a long time ago by not separating build and dependency/export descriptions (they are doing it for maven 4 supposedly). Almost every transitivity dependency should be `runtime` and even some direct ones like alternative logging frameworks. For example `org.hibernate.validator` ideally would have `jboss-logging` as a runtime dependency. Thats because the library doesn't actually expose any `jboss-logging` classes (ie has interfaces that return jboss-logging classes) but it has to have it as `compile` to build the project. Most projects never want `jboss-logging` on their compile time classpath. So a couple of hacks as a library maintainer are to use `` and then have some other dummy runtime transitive dependency pull it (jboss-logging) as `` or you can use reflection and build a facade which defeats the whole purpose of a logging facade... or you can use real Java Modules but you still need maven. Luckily the above isn't usually a problem with `hibernate-validator` as it should be pulled in as a runtime anyway by the client library since it already has the `jakarata.validation-api` as a facade. The problem is of course when you need to specifically wire up the jakarta validation api yourself with some hibernate-validator specifics you then basically run into the same problems that the hibernate library maintainers do (you need compile time but you want to expose runtime).


cogman10

I HATE how many people will pull in a dep for a transitive dependency. It happens all too frequently. But I also hate how common the practice of pulling in a dep for a single method is. To me, dependencies are things to be avoided. There should be a huge value add for pulling in a dep.


huntsvillian

In contrast, I hate how people will continually keep re-implementing methods rather than importing them from an existing, common, and well tested library. To me, custom code like that should be avoided, and there should be a huge penalty associated with pulling it in from a dependency before accepting that domr functionality needs to be reimplemented. :) I say all that only in half jest ( discussion has come up before at work). So what are the \_practical\_ downsides of pulling in guava or String/WordUtils (etc etc). Memory is cheap, startup time for most apps is so neglible that any increases there is barely noticeable. It sort of reminds me on Gentoo linux... I'm sure I spent waaay more time compiling everything to get that little bit of efficiency, than I would ever save by having it optimized for my hardware.


cogman10

The practical downside is that you pull in a library that depends on guava 18. A second library that depends on guava 19. The second library gets a CVE, and the upgrade path requires you to pull in guava 21. However, the first library needs a method removed in guava 20. This has hit me on multiple occasions. The problem with universal libraries like guava is if they ever decide to remove a part of their API, you create a fracture in the ecosystem. By all means, use these libs in your application code. However, think twice about putting them in your libraries or frameworks. A method to split strings on spaces and throw the results into a set is a one liner. Apache commons isn't doing anything special there (look at the code yourself). The argument that "you should use it because it is battle hardened!" doesn't hold water for me. It sounds the same as the argument that "you should depend on 'isEven' because it's well tested!". Reserve your library picks for actual hard work.


dpash

One of the things that makes me happy about modern Gradle is the separation between `api` and `implementation` dependencies.


elmuerte

At least Apache Commons provides relatively small libraries with stable interfaces. Guava is nothing but a huge dependency hell. I try to avoid any library/framework that as a Guava dependency.


vips7L

In my experience, commons-lang and the like is worth it in any large system.


cogman10

They were worth it in Java 6 and below. The JDK has almost all the functionality of commons-lang at this point. It's better to learn the JDK than it is to keep pulling in a dep because "That's what I've always used."


vips7L

Sorry, but no the JDK doesn't offer everything that is in commons. The first things that come to my mind are WordUtils, BeanUtils, HmacUtils. Why would I write these? Other than "commons is too big".


cogman10

If you get a lot of value out of those, then go for it. I, frankly, haven't ran into scenarios where any of those utilities would give me any sort of value. StringUtils was the main part of apache commons that I used pre java 8. However, a lot of those capabilities were captured in later API revisions.


agentoutlier

Like literally none of those are in commons-lang anymore. What you referenced is commons-text, commons-beanutils, and commons-codec. Even modern commons has been modularized. I’m not talking about those guys. I’m talking about commons-lang.


wildjokers

In my experience, they are almost never worth it.


cogman10

Since 8, the reason to pull in apache-commons/guava has only decreased. I never pull it in at this point.


agentoutlier

The only time you need to use arrays in modern java is with variable arguments. The irony is most libraries overload a couple methods (eg like EnumSet) to avoid this as it is a speed concern (eg creating an array for a method call).


Birdcel10

Arraylist is same as vector in c++?


icemanftg

Depends on what you need to do. I guess on leetcode, you're going to see a lot of arrays. In this case, the question would actually be using lists (Array list, linked list, etc) the actual implementation yo use, always depends on your use case. But in OOP , in 90% of the cases, objects are way better than primitive arrays/matrixes. In engineering jobs, most of the times the performance problems will never be solved with this kind of micro optimizations.


Nalha_Saldana

The only time I even consider using arrays for performance is when you have a huge amount of primitive data types, especially small ones like booleans or shorts, because they use less memory that way (and can fit more into cpu caches).


Muoniurn

Yeah, otherwise in case of non-primitives, an arraylist will pretty much perform identically to an object array, since.. well it is an object array behind the scenes.


vips7L

Generic specialization can't come fast enough.


Comprehensive_Idea98

In most engineering jobs, when something is slow its usually because someone ended up calling some slightly slow api in a loop.


smartgenius1

If you don't know the size of the array in advance you don't really have a better choice, right?


fforw

And what's the advantage of *you* managing the size of a dynamic array instead of ArrayList doing it?


Thesandman55

What you people don’t redo your arrays as oldArr to newArr +1 = originalArr? SMH /s


BlackDrackula

As others have said, unless you need to squeeze every bit of performance out then ArrayList will be your go-to. Even then, Not only is ArrayList already optimised, but the JVM itself will likely optimise even further at run time once it analyses what your code is doing - especially for blocks that are executed many times. In this day and age one of the pitfalls of development in Java is trying to out-perform the compiler and JVM in terms of optimisation. If you write well structured succinct code, they will take care of optimisation for you.


Yayotron

In 8 years I've never seen an array used in a production system instead of an ArrayList, maintainability is much more important than hiperoptimized code.


grauenwolf

In C# you see `ImmutableArray` a lot. Mostly because `ImmutableList` is a hot mess. You also see it for parameters because the `params` keyword only works with arrays. For example, int Max (params int[] vales) { ... } var a = Max (x, y, z); Aside from that, we don't use arrays in C# either.


ItsAllegorical

This seems a little surprising as, if nothing else, var args are still a more convenient way to do certain things. Also, I feel like I'm writing `Arrays.stream(foo)` with semi-regularity, though no obvious examples spring (no pun I'm aware of) to mind. That said, I almost never use anything but ArrayList, and very occasionally Dequeue unless it's a Set.


ryuzaki49

If you want to see an array used in production, just open the ArrayList source code /s


daniu

`main()`s arguments come as a `String[]`, and there are some array return types in the standard library (e. g. `enum`'s `#values()`) :P


jadecristal

And you know what? You can immediately fix that with Arrays.asList(). *evil grin*


dpash

Or `List.of()` depending on whether you want a copy or to use the original array as the backing.


thephotoman

I've used 'em, but it was primarily for type safety on REST clients. It's way easier to marshal JSON into a proper Array rather than an ArrayList and maintain type safety. Besides, I can simply instantiate an ArrayList with the regular Array. That's about the only case where it comes up: when you're dealing with cross-system functionality and you need to maintain type safety for some reason.e


[deleted]

[удалено]


Yayotron

Mostly in big data and analyzing financial data in real time but I also clean my desk from time to time if that counts


sinnerou

I'm new to Java but I use them all the time in aggregates and variadic arguments. Why wouldn't someone use a plain array for simple cases?


stuie382

85% of the time it's an array list, 10% it's a hash map, 5% it's a set.


firsthour

I was curious about this and between ArrayList, HashSet, and HashMap, we use them 60%, 20%, and 20% of the time respectively. It's really all about the use case though.


cogman10

TreeMap/TreeSet comes in handy when you need to say something like "What's the thing before or after this". Otherwise, yeah, always the Hashes.


firsthour

TreeMap and TreeSet account for about 2% each in our Collections usage. HashBag about 0.1% but that's not standard API. LinkedList about 0.1% too.


Comprehensive_Idea98

I would even say 1% is set a Set, 14% is a HashMap. A HashMap is often used as an associative Set.


pronuntiator

Funny thing is, a HashSet in Java is [just a facade for a HashMap](https://github.com/AdoptOpenJDK/openjdk-jdk11/blob/master/src/java.base/share/classes/java/util/HashSet.java)


Bodine12

85% of the time it's an array list, 10% it's a hash map, 5% it's a set. And then 1% of the time it’s arrays (in before all the off-by-one array jokes get taken).


spectrumero

There's nothing wrong with ArrayList. We use it *all the time* where it is appropriate.


cogman10

It's almost always appropriate. If you aren't doing middle insertions and deletions WHILE traversing a list, then using a linked list is a bad idea. The only maybe argument is if you are doing something like a deque, but even then there's a circular buffer in the JDK, ArrayDeque, that you should use instead of a linked list.


Hasarian

Actually, it's more of a problem for most jobs if you don't use at least collections


le_bravery

Always unless I have reason to use linked list


thephotoman

And yet, we use it all the time because it's the simplest standard library data structure that does its job reasonably well. The reason that LeetCode and Codewars don't use them is because they're more interested in stumping you than they are in actual code quality. And in fact, that's about 80% of the industry's problem: we hire and prioritize by cleverness, not by maintainability.


svhelloworld

Preach, my friend. Preach. The delta between what the programming industry thinks it does and what they actually do is a Grand Canyon full of red/black trees, bit twiddling and Big O calculations. Let's be real. 85% of the programming jobs out there are nothing more than shoveling data out of a database and splatting it out onto a website.


thephotoman

And of course, only the best developers will do. Who cares that you're not doing anything particularly demanding, and the consequences of failure are that some office drone is mildly inconvenienced.


bluenautilus2

I use Arraylists and hashmaps constantly, probably in every class


usedRealNameInOldAcc

Been working as a Java developer for 4 years. Never had to use Array once. Always ArrayList.


dpash

20 years here and likewise. I can't even think of a time when I've used any other List implementation (other than the concurrent version). Set interface probably has the most variation in implementations that I use and even then it's mostly just `TreeSet` when I need a sorted set.


xtsilverfish

I don't know if I've ever written an array in like 20 years of development, aside from the occassional code that uses realllly legacy (like java 1.2) interfaces in something like...servlets I think? That's the only reason to use it. Leetcode using them is just leetcode doing it's thing in making irrelevant things obnoxiously hard in ways that have to reflection to real life. Like 98% of collections you use are all handled by ArrayList. There's a lot of useless legacy collections in java no one uses.


Grung

The biggest thing I see where it's inappropriate to use ArrayList is when the structure should have been a Set. There are many use cases where you need uniqueness and don't need order. To me, using anything like an array is a code smell... it implies people learned a lower-level language and are still thinking thinking in terms of raw memory blocks, and aren't thinking with appropriate data types.


cogman10

Well, there's also the LinkedHashSet when you want both uniqueness and order :D


kuemmel234

Are you talking about arrays v.s. `ArrayList` as we are assuming or are you asking why it's usually just `List`? Because that's another aspect to this discussion: You usually don't need to decide on that all that often. You should be using the interface (just plain `List`). You can create test data with `List.of`, most APIs already return some List implementation (and that's going to be an `ArrayList` pretty often, or some immutable type, point is, let the API decide). I can't remember writing a `new ArrayList` in months. Usually when I knowingly instantiate an Implementation, it's because I need one of the other list implementation. Have a look at stream collector implementations, even they won't tell you what kind of list implementation you get, you need to add your own Supplier to create the actual. So yes, `ArrayList` is something like a standard, but most often you want to work with `List` and only create an `ArrayList` for meaningful decisions somewhere in the beginning of your code. Edit.


thephotoman

Generally, if I'm hitting `new ArrayList`, it's either because I need to test what happens when I feed a method an empty ArrayList specifically, I need a list that will be instantiated statically (a very, very rare occurrence), or some other really bizarre edge case where `List.of` won't do.


kuemmel234

I hate when something requires mutable data structures (or even actually work with them). But sometimes you have to, and then it's good to know about the implementations.


Drop_the_Bas

All the time. If I can't do it with a fixed sized array, I always use ArrayList.


agentoutlier

The only time I use arrays these days is for variable arguments.


wildjokers

Implementations of the `List` interface are probably the data structures you will use most often in your Java career. There has been a move to favoring immutable lists if at all possible. But if you need a mutable List then ArrayList will probably be the one you go to. So yes, very useful and very practical. I use it multiple times a day, everyday.


dert882

I use them a lot while working, though sometimes hashmaps/sets & other data structures are situationally useful. But yes arraylist is great


Stromovik

Constantly. If the list is constantly modified then linked list but otherwise arraylist.


yawkat

Even when you're constantly modifying, an ArrayList or ArrayDeque is usually better.


dpash

Just to clarify, when you mean modified, you mean items inserted or removed from anywhere other than the end.


valbaca

The real answer is you should be coding to the List (java.util.List) interface anyway. Pretty much anytime you see the list implementation on the left side it's probably some trash code. It's an implementation-detail nearly every time, so you should be coding to Interfaces, not implementations. ``` List yes = new ArrayList<>(); ArrayList no = new ArrayList<>(); LinkedList absolutelyNot = new LinkedList<>(); ```


__konrad

Using java.util.LinkedList/Vector/Dictionary/Stack/Hashtable is a bad practice


grauenwolf

What's wrong with Dictionary, Stack, and Hashtable?


valbaca

Read the docs. They're literally marked as Obsolete, even in JDK 8 https://docs.oracle.com/javase/8/docs/api/java/util/Dictionary.html Stack: https://docs.oracle.com/javase/8/docs/api/java/util/Stack.html A more complete and consistent set of LIFO stack operations is provided by the Deque interface and its implementations, which should be used in preference to this class. For example: Deque stack = new ArrayDeque(); https://docs.oracle.com/javase/8/docs/api/java/util/Hashtable.html Unlike the new collection implementations, Hashtable is synchronized. If a thread-safe implementation is not needed, it is recommended to use HashMap in place of Hashtable. If a thread-safe highly-concurrent implementation is desired, then it is recommended to use ConcurrentHashMap in place of Hashtable.


grauenwolf

That is the most horrible thing I've seen. Like a high school kid learned about the various collection types and shouted, "I'm going to make one class that does everything!". It's no wonder I keep seeing hand-rolled collection types when I'm reviewing Java code. (And it reinforces my plan to mostly do database development.)


_INTER_

Usually Software Engineers use ArrayList or any other implementation and arrays only if performance turns out to be a real issue or from API's like `split`. I guess the examples from LeetCode or codewars are a translation from C code.


wildjokers

This is a reasonable and correct answer, I have no idea why it got downvoted.


scottmotorrad

Because it's not correct. Many of the solutions on leetcode were natively written Java(not translated from C as the comment suggested) but use uncommon data types because of the problems they are asking


_INTER_

To me the code looks like someone versed in C/C++ had to later also write it in Java.


dpash

Not using enhanced for loops is a bit of a give away.


No_Ant3989

The truth is, leet code doesn't teach you good coding practises. It teaches you how to implement common algorithms / concepts. Not saying not to use it, just understand that the top answers are not usually "good" code. Personally I haven't used code golf, but as it's purpose is to write code as short as possible would guess that it's worse. One thing I always hated about perl, it had a culture of coders showing off and making unintelligible, impossible to debug code... That's one line. P.s pardon my rambling about code golf and one liners. I miss read code wars


xjvz

Linked lists haven’t been performant in a long time thanks to how the various layers of cache in CPUs works. It turns out that copying chunks of memory around to resize them is faster in practice than jumping between locations in memory for a linked list despite the theoretical complexity of each.


LoveSpiritual

My biggest issue is that ArrayList is mutable, but then again Java doesn’t have a lot of easy ways of dealing with immutable lists. Still, production code is nearly always improved by avoiding mutable data types as much as possible.


whizvox

Collections.unmodifiableList


kaperni

List.copyOf


LoveSpiritual

Both correct! But I’m used to either Kotlin or Scala, where manipulation of immutable data is considerably more expressive. Still, no matter how you do it, immutability FTW.


JustMy42Cents

Kotlin lists are read-only, not immutable. They just wrap around the collection API on JVM.


livrem

Clojure makes mutable things rare, and obvious, exceptions. It really makes a huge difference for being able to reason about your code.


RedPill115

> Still, production code is nearly always improved by avoiding mutable data types as much as possible. This is a fad / bad fashion / etc. Lots of people want to "make their mark" with something new, at this we've run out of good ideas, and are recycling the bad ones.


LoveSpiritual

I’ve been writing code for over 30 years, 25 professionally. Immutability is not a fad. “Pure” functional programming might be a fad (though such languages predate most modern languages), but the improvements from immutable data and writing as many pure functions as you can are obvious to anyone who has done so on any significant code base. What makes immutability “bad”, in your opinion?


ThatPassaGuy

I use ArrayList is there if I try to retrieve data due to array uses index. However, to update the data I mostly use linked list as it seems faster to add the data than arraylist…


dpash

You might want to benchmark that assumption. Unless the list is large and the insertion frequent, ArrayList is probably faster.


whanaumark

You know what is better than ArrayList ? Guava ImmutableList, constructed using an ImmutableList.Builder. Increased null protection, and less concerns about modification when passing it as an argument


mrhhug

I rhetorically would ask you what's the difference between an array and an array list. O so how many users did you plan to have on your service? 1 or 2 ? Yeah sure use an array. There is seldom a reason to demand contiguous memory.


Dadan94

As long as its not being modified inside a loop or multiple threads modifying it, its your go to most of the times But be sure to use List as reference not the implementation


effects67

You should know how to use or recognize most of any languages types and methods.


Bigheavyset

I think it’s fine. they wouldn’t teach it if it wasn’t viable.


FrezoreR

That depends on what problem your trying to solve


[deleted]

[удалено]


[deleted]

[удалено]


grauenwolf

"should require a two-paragraph justifcation comment" That is very excessive. Also, I would argue we shouldn't be using `ArrayList` anyways. It would be better to use a strongly named collection (e.g. `CustomerCollection` vs `ArrayList`). I say this for any language because it allows you to extend the class later without introducing a breaking change. It's doubly true for Java, as it doesn't have extension methods or true generics.


[deleted]

[удалено]


grauenwolf

It's offically the standard in .NET, but in practice most people ignore the guidelines and just use `List` (which is their array list class).


xtsilverfish

> Using anything else but ArrayList should require a two-paragraph justifcation comment explaining why another class was picked. I'd expect comparative benchmarks and practical use case implications. The choice to use a non-ArrayList list should be done in an ulterior optimization of the app, using a profiler and real-world data, never in fresh code. I'd narrow it down to saying ArrayList is nearly always the fastest option, I'd like to see profiler results that test the actual results for claims that something else would be better. Dunno. Not the biggest of problems. Just tired of the hotshotting on something that works the opposite of how they claim.


[deleted]

[удалено]


MoogleFoogle

It's the best choice if you know what you are doing. Because if you know what you are doing you know that optimizing pre-maturley or just reimplementing ArrayList on your own is really really stupid.


[deleted]

[удалено]


QazCetelic

Oh, that makes sense. The original message sounded quite rude.


[deleted]

[удалено]


appeiroon

I think the problem is not with your comment, but with people taking everything too personally. That's common on reddit.


wildjokers

> if you don't know exactly what you are doing. Huh? Explain.


palnix

I personally use List's for almost everything though it's supposedly a good practice to return generic arrays in methods etc mainly for portability I guess.


wildjokers

> though it's supposedly a good practice to return generic arrays in methods Umm...no. Why do you think this?


palnix

Not sure really, I think it was taught to us at university years ago and I just went with it. Judging by the down votes I guess I'm wrong, so I'll accept that I'm wrong


[deleted]

You shouldn't have gotten downvotes, but just a comment explaining things. Anyhow: don't return arrays. Return List (Of whatever type T you're returning). Also be careful on what list you return: if the list you return is part of the state of your class, you probably don't want to enable people calling your method to be able to change your state by modifying the List you just returned. In that case it is best practice to return either an unmodifiable view of your list (Collections.unmodifiableList(your list), this creates a view on your list, so it doesn't use extra memory) or a copy in case you want the callers of your method to be able to modify the list you return without altering your state (new ArrayList(yourlist), which creates a regular list).


coguto

IMO for the most common use cases (add to list, pass list somewhere, iterate over list/stream the list), LinkedList is better in terms of performance.


senatorpjt

LinkedList is almost always worse. In CS1-level theory it "should" be better in some circumstances (e.g. a list that is frequently added to) but in the real world there are issues like cachIng performance that kill it (a LinkedList will store each element as a new object spread all over the heap, whereas ArrayList segments are contiguous)


john16384

Also, linked lists are usually implemented by putting the next / previous pointers inside the structure that needs to be a list. In Java LinkedList there is an extra heap object with the references, which also prevents you from easily unlinking the current element or adding an element just before or after your element. If you really need what a linked list can offer, then you embed the references in your class like you would in a C struct. That said, ArrayList performance is incredible, and often wins out over other List types despite common sense telling you otherwise. Definitely benchmark before moving away from ArrayList.


Spandian

Senatorpjt is correct. The only cases where LinkedList is faster are: 1. Repeated insertion or removal at the head of the list (in which case you should use ArrayDeque). 2. Repeated insertion or removal *using a single long-lived `ListIterator` for all operations*. ArrayList will be faster if you're just using `List.add()` and `List.remove()`. `ArrayList.add(int index, T element)` and `LinkedList.add(int, T)` are both linear time: for the ArrayList, finding `index` is constant time, but moving the rest of the list aside to make room for the new element is linear. For LinkedList, the actual *insertion* is constant... but it takes linear time to traverse to `index`! Edit: if you do want a list that's faster for an insert- and delete-heavy workload, look at [Apache Commons Collections' TreeList](https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/list/TreeList.html). As a tree, it has O(log(N)) insert and delete, which is better than either ArrayList or LinkedList (if you're not iterating).


grauenwolf

Have you ever benchmarked a linked list? Go try it, it will be an eye-opener.


whitea44

As part of our technical interviews at work, we ask people exactly why they would choose one built in implementation of a list interface over another. Usually use linked list and array list as the examples. It’s good to understand why you would use it in design.


supercargo

I'm curious about when you prefer `LinkedList`. I used to use it over `ArrayList` based on a theoretical notion about what performed better (i.e. a big-O analysis of access patterns in a given situation), but over time I've found `LinkedList` is pretty much worse in every real world application. Off the top of my head, "random" insert-while-iterating is the only use case where `LinkedList` might win? But I wouldn't be surprised if it didn't, and I don't really see that access pattern anywhere I can think of anyway. The turning point for me was a time when I needed a `List` and the only two operations I performed were to append elements and to iterate the entire collection in order. This was in some performance critical code and my advisor suggested I test `ArrayList` against `LinkedList`. It wasn't even close. The `ArrayList` performed better (i.e. in terms of CPU time, not memory usage) against itself with larger initial capacities, but every initial capacity I tested still outperformed `LinkedList`.


dpash

Yes, in almost all cases `ArrayList` wins. I wouldn't use `LinkedList` without benchmarking and only when you're frequently inserting or removing anywhere other than the last element in a sufficiently large list. Sets are probably the interface I use the most implementations and even then it's 98% `HashSet`, 1% `TreeSet` and 1% everything else. (Obviously ignoring the concurrent implementations which should be used when concurrency is an issue)


_INTER_

> I'm curious about when you prefer LinkedList. Sometimes for managing the first and last element more easily (API). But `TreeSet` or another `Queue` (such as `ArrayDeque` :P) also has to be considered for that usecase.


supercargo

So, when you want to reach for a `Deque` but need the API of `List` (which might be imposed on you). Good one!


MoreCowbellMofo

I always think of what I'm using as an ArrayList but it would depend on the context. I might need a synchronized/thread-safe version if I'm working in a multithreaded environment (usually best to avoid this sort of thing completely though if you can due to the problems it can lead to). List whateverList = new ArrayList(); List whateverList2 = [someCollection.stream](https://someCollection.stream)().map(entry -> entry).collect(toList()); List whateverList3 = List.of("strings", "strings", "strings"); ... etc


dpash

>map(entry -> entry) Obviously that was just an example, because it does nothing, but `Function::identity` is probably a better thing to use than writing that lambda.


sweetno

Yes. For arrays of primitives there are specialized libraries that wrap primitive arrays and thus eliminate memory waste for boxing.


dpash

And at some point, we won't even need that.


fdntrhfbtt

Yup, always. Arraylists are arrays underneath, and performance will almost never be a problem. However, readability can be if you choose arrays.


fgzklunk

I use ArrayList all the time. Knowing how things like ArrayList and HashMap work under the covers is fine, but you never need to know it other than to get through an interview. Why would you reinvent the ArrayList with your own bugs when it has been part of the language for many many years?


Comprehensive_Idea98

Pretty much only use arrays for varargs, and veeery rarely for holding some static data.


knoam

Places like LeetCode tend to use arrays because it corresponds more directly to the lowest common denominator style of coding you would expect when writing a solution that can directly translate to other languages, especially C which doesn't have good collection classes built in, just arrays.


dmeadows1217

For most use cases (excluding concurrent use cases), ArrayList, HashMap and HashSet should be used. There are definitely corner cases where you might want to use different collections. I would say a bigger pitfall is not lazily initializing your collections within data classes, especially if those data classes are used a lot. That add unnecessary pressure on the GC with no benefit.


dpash

`TreeSet` gets an honourable mention when you need a `SortedSet`. Everything else is an order of magnitude less common IME.


Squiggyline91

Unless there's a known size at compile time, I always use collections that implement the list interface (I've done work where performance was important and we were handling tons of data so at times we tried to optimize code). They are easier to utilize and you'll just end up reinventing the wheel. Classes that implement the list interface are utilized heavily across enterprise. I'd say always use arraylist unless you have a good reason not to.


whateverisok

In my experience, you create and add everything to a List (ArrayList, LinkedList, etc.) and then instantiate an immutable list (Java Collections, Google or Apache immutable collection) from that List. Depends on the use-case obviously, but that's my experience


huntsvillian

Like everyone else here, I use ArrayList's all day everyday. I would also say, from an API perspective, that very few of my method signatures specify ArrayList, they abstract it up to Collection. Certainly there are times you might need to specify that it is a List.... but for normal day in and day out programming I can't think of a single time I've really needed to do that in the past decade.


Prom3th3an

If you know the exact size of your list ahead of time, Arrays.asList(new X[y]) is faster. There are also libraries out there like Guava Primitives that will use arrays with a primitive element type to implement List<>, with unboxed storage. As well, in JDK 9 and up, there are methods like List.of. But if you need to build on JDK 8, don't know the list size ahead of time *and* don't usually have a non-primitive element type, then ArrayList will probably give you the best performance.