int[] cats = new int[10] в памяти выглядит как непрерывная область память заполненная значениями и равная sizeof(int) * 10. Преимущества - если вы часто обращаетесь и бегаете по коллекции элементов то массивы обеспечат вам максимальную производительность только за счет индексной адресации и меньшего количества кэш-мисов (гуглить свойство локальности данных). Минусы - фиксированный размер, заресайзить можно до не удобно и дорого в плане производительности.
ArrayList же это список, обычный такой вот список. То есть каждый элемент связан друг с другом через указатели. Плюсы - легко добавлять и удалять элементы. Минусы - элементы созданные в разное время могут оказаться в память черти где, что может привести к большому количеству кэш-мисов. Короче траверсинг по списку банально медленнее.
В зависимости от задачи имеет смысла выбирать то или иное решение.
Updated: справедливости ради поправлю себя же. ArrayList это реализация списка на массивах, так что все чуть сложнее. Описанный мной случай - LinkedList, но суть все та же - просто массивы - фиксированный размер, ArrayList - размер динамический.