В Array строго указывается размер и больше не изменяется.
List - это обертка над Array с возможностью добавления элементов и другими менее значимыми плюшками.
ArrayList старый недженериковый тип, наследие темных времен. Его можно забыть.
Во всех стандартных случаях следует использовать List и передавать в него параметр capacity, если заранее известно кол-во элементов, которое в него добавится.
Array следует использовать в особых случаях, когда нужен ArrayPool, stackallock и прочие узкоспециализированные вещи. Но если вы ими занимаетесь, то и сами все знаете.