A list is great when order matters and repeats are fine. Sometimes you want the opposite: a bag of values where each value appears once and the order does not matter. That collection is a Set.
You declare a set by naming the type it holds inside angle brackets:
Set<String> tags = new Set<String>();
tags.add('urgent');
tags.add('review');
// tags now holds urgent and review
You can also fill a set at the moment you create it, or build one directly from a list:
Set<Integer> codes = new Set<Integer>{ 100, 200, 300 };
List<String> names = new List<String>{ 'Ana', 'Miguel' };
Set<String> nameSet = new Set<String>(names);
add(value) puts a value into the setcontains(value) hands back true if the value is already theresize() tells you how many values the set holdsremove(value) takes a value back outisEmpty() tells you whether the set holds nothing at allSet<String> tags = new Set<String>{ 'urgent', 'review' };
Boolean isUrgent = tags.contains('urgent'); // true
Integer howMany = tags.size(); // 2
A set has no positions, so there is no tags.get(0). Asking a set for its first element is not a thing you can do. If you need to look at every value, use a for-each loop, and do not count on the order staying the same.
contains() is the reason sets exist. Checking whether a value is already in a set is fast and reads clearly, which makes sets the right tool for membership questions like "have I already seen this record id".