Dart 언어는 강력한 타입 시스템과 함께 매우 뛰어난 콜렉션 라이브러리를 제공합니다.
    Dart에서의 콜렉션이란 데이터를 저장하고 조작할 수 있는 객체를 의미합니다.
    본 글에서는 List, Set, Map이라는 세 가지 주요 콜렉션에 대해 자세히 알아보고, 다양한 사용법과 예제를 통해 각 콜렉션의 특징을 설명하겠습니다.
1. List
    List는 순서가 있는 데이터를 저장하는 콜렉션입니다.
    Dart의 List는 배열(array)와 유사하게 동작하지만, 크기가 동적으로 변경될 수 있습니다.
    List는 같은 데이터 타입의 객체 뿐만 아니라 다양한 데이터 타입의 객체도 저장할 수 있습니다.
1.1. List 생성
void main() {
    // 빈 리스트 생성
    List<int> numbers = [];
    
    // 초기 값으로 리스트 생성
    List<String> fruits = ['Apple', 'Banana', 'Cherry'];
    
    // 리스트의 크기 지정
    List<double> temperatures = List.filled(5, 0.0);
    
    print(numbers); // []
    print(fruits); // [Apple, Banana, Cherry]
    print(temperatures); // [0.0, 0.0, 0.0, 0.0, 0.0]
}
1.2. List의 주요 메서드
    List 객체에는 데이터 조작을 위한 여러 가지 메서드가 있습니다.
    몇 가지 주요 메서드와 그 사용 예제를 소개합니다.
void main() {
    List<String> fruits = ['Apple', 'Banana', 'Cherry'];
    // 추가
    fruits.add('Dragonfruit');
    print(fruits); // [Apple, Banana, Cherry, Dragonfruit]
    // 여러 개 추가
    fruits.addAll(['Elderberry', 'Fig']);
    print(fruits); // [Apple, Banana, Cherry, Dragonfruit, Elderberry, Fig]
    // 삭제
    fruits.remove('Banana');
    print(fruits); // [Apple, Cherry, Dragonfruit, Elderberry, Fig]
    // 인덱스 사용
    String firstFruit = fruits[0];
    print(firstFruit); // Apple
    // 길이
    int length = fruits.length;
    print(length); // 5
}
1.3. List의 반복 처리
List에 저장된 데이터에 대한 반복 처리는 for 루프, forEach 메서드를 통해 수행할 수 있습니다.
void main() {
    List<String> fruits = ['Apple', 'Banana', 'Cherry'];
    // for 루프 사용
    for (var fruit in fruits) {
        print(fruit);
    }
    // forEach 메서드 사용
    fruits.forEach((fruit) {
        print(fruit);
    });
}
2. Set
    Set은 중복되지 않는 유일한 객체의 모음입니다.
    Set 콜렉션은 요소의 순서에 의존하지 않으며, 값의 존재 유무만으로 데이터를 관리합니다.
    Dart에서 Set은 추가, 삭제, 포함 여부 확인 등을 빠르게 수행할 수 있습니다.
2.1. Set 생성
void main() {
    // 빈 세트 생성
    Set<int> uniqueNumbers = {};
    
    // 초기 값으로 세트 생성
    Set<String> uniqueFruits = {'Apple', 'Banana', 'Cherry'};
    
    print(uniqueNumbers); // {}
    print(uniqueFruits); // {Apple, Banana, Cherry}
}
2.2. Set의 주요 메서드
Set 객체에도 다양한 메서드가 존재합니다.
void main() {
    Set<String> uniqueFruits = {'Apple', 'Banana', 'Cherry'};
    // 추가
    uniqueFruits.add('Dragonfruit');
    print(uniqueFruits); // {Apple, Banana, Cherry, Dragonfruit}
    // 중복 추가는 무시됨
    uniqueFruits.add('Apple');
    print(uniqueFruits); // {Apple, Banana, Cherry, Dragonfruit}
    // 삭제
    uniqueFruits.remove('Banana');
    print(uniqueFruits); // {Apple, Cherry, Dragonfruit}
    
    // 길이
    int length = uniqueFruits.length;
    print(length); // 3
}
2.3. Set의 반복 처리
Set도 List와 마찬가지로 반복 처리를 지원합니다.
void main() {
    Set<String> uniqueFruits = {'Apple', 'Banana', 'Cherry'};
    // for 루프 사용
    for (var fruit in uniqueFruits) {
        print(fruit);
    }
    // forEach 메서드 사용
    uniqueFruits.forEach((fruit) {
        print(fruit);
    });
}
3. Map
    Map은 키와 값의 쌍으로 데이터에 접근하는 유용한 콜렉션입니다.
    키는 고유해야 하며, 각각의 키는 하나의 값에만 연결될 수 있습니다.
    Map을 사용하면 데이터의 빠른 검색 및 관리를 할 수 있습니다.
3.1. Map 생성
void main() {
    // 빈 맵 생성
    Map<String, int> fruitPrices = {};
    
    // 초기 값으로 맵 생성
    Map<String, String> countryCapitals = {
        'USA': 'Washington D.C.',
        'France': 'Paris',
        'Japan': 'Tokyo',
    };
    
    print(fruitPrices); // {}
    print(countryCapitals); // {USA: Washington D.C., France: Paris, Japan: Tokyo}
}
3.2. Map의 주요 메서드
Map에서도 다양한 메서드를 통해 데이터 조작이 가능합니다.
void main() {
    Map<String, int> fruitPrices = {
        'Apple': 3,
        'Banana': 1,
        'Cherry': 5,
    };
    // 추가
    fruitPrices['Dragonfruit'] = 4;
    print(fruitPrices); // {Apple: 3, Banana: 1, Cherry: 5, Dragonfruit: 4}
    // 수정
    fruitPrices['Banana'] = 2;
    print(fruitPrices); // {Apple: 3, Banana: 2, Cherry: 5, Dragonfruit: 4}
    // 삭제
    fruitPrices.remove('Cherry');
    print(fruitPrices); // {Apple: 3, Banana: 2, Dragonfruit: 4}
    // 키 존재 여부 확인
    bool hasBanana = fruitPrices.containsKey('Banana');
    print(hasBanana); // true
    // 길이
    int length = fruitPrices.length;
    print(length); // 3
}
3.3. Map의 반복 처리
Map의 모든 키와 값에 대한 반복 처리는 다음과 같이 수행할 수 있습니다.
void main() {
    Map<String, int> fruitPrices = {
        'Apple': 3,
        'Banana': 1,
        'Cherry': 5,
    };
    // keys() 메서드로 반복
    for (var key in fruitPrices.keys) {
        print('Fruit: $key, Price: ${fruitPrices[key]}');
    }
    // entries() 메서드로 반복
    fruitPrices.forEach((key, value) {
        print('Fruit: $key, Price: $value');
    });
}
결론
    Dart의 List, Set, Map은 각각의 특성과 장점을 가지고 있어 다양한 상황에서 효과적으로 데이터를 관리할 수 있습니다.
    List는 순서가 있는 데이터 컬렉션, Set은 고유성을 보장하는 컬렉션, Map은 키-값 쌍으로 데이터를 관리하는 데 적합하다는 점을 이해하는 것이 중요합니다.
    이를 통해 다양한 프로그래밍 문제를 해결하고, 깔끔하고 효율적인 코드를 작성할 수 있습니다.