Dart 컬렉션

1. Dart 기본 내장 세 가지 컬렉션

Dart에는 기본적으로 세 가지 컬렉션이 내장되어 있습니다:ListSetMap

컬렉션 내부 요소 타입 제한은제네릭(Generics)으로 설정할 수 있습니다.

컬렉션 타입핵심 특징리터럴 기호
List순서 존재, 중복 허용, 인덱스 접근 지원[]
Set순서 없음, 요소 유일, 인덱스 없음{} (제네릭 명시해야 Set으로 인식)
Map키-값 쌍 저장, Key는 유일, Value는 중복 가능{key: value}

2. List 리스트 (순서 배열)

1. 기본 정의 및 타입 추론

  • Dart의 배열은 본질적으로 List 객체이며, 리터럴 []로 생성;
  • 타입 자동 추론 예시:var list = [1,2,3]List<int>,int 외 타입 삽입 시 오류;
  • 끝 쉼표 지원, 문법에 영향 없어 복사 붙여넣기 오류를 줄임:var list = ['Car', 'Boat', 'Plane',];

2. 기본 조작

  1. 인덱스 규칙:0부터 시작, list.length - 1가 마지막 인덱스;
  2. 요소 읽기/수정:list[index]list[index] = 새값
  3. 길이 얻기:.length 속성;

예시

void main() {
	var list = [1,2,3];
	print(list.length);//요소 개수 3 출력
	print(list[1]);// 2 출력
	list[1] = 9; //두 번째 요소를 9로 수정
	print(list[1]);//수정 후 값 9 출력
}Code language: Dart (dart)

3. 상수 리스트 (컴파일 타임 불변)

리터럴 앞에 const를 붙이면 런타임에 요소 추가/삭제/수정 불가:

void main() {
	var constantList = const [1,2,3];
	constantList[1] = 100; // 컴파일 오류
}Code language: Dart (dart)
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Unhandled exception:
Unsupported operation: Cannot modify an unmodifiable list
#0      UnmodifiableListMixin.[]= (dart:_internal/list.dart:89:5)
#1      main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:4:14)
#2      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#3      _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)Code language: PHP (php)

3. Set 집합

순서 없고 요소 중복 불가

1. Set 핵심 특징

  • 순서 없음:요소에 고정 인덱스가 없어 [인덱스]로 값을 읽거나 수정할 수 없음
  • 요소 유일:자동 중복 제거, 중복 요소 추가해도 오류 없고 한 개만 유지
  • 리터럴 기호:중괄호 {}
  • 제네릭 제약:단일 타입만 저장하도록 제한 가능, 다른 타입 삽입 시 컴파일/런타임 오류

빈 Set과 빈 Map 구분 (실수하기 쉬운 부분)

{}는 기본적으로 Map으로 인식하므로 빈 Set 생성 시 제네릭을 명시해야 함

void main() {
	// 빈 Set<String>
	var names = <String>{};
	Set<String> names2 = {}; // 동일한 표기법

	// 제네릭 없으면 Dart가 Map<dynamic, dynamic>로 판단
	var names3 = {};
}Code language: Dart (dart)
타입 추론
void main() {
	// Set<String> 자동 추론
	var halogens = {'dog', 'cat', 'horse'};

	// Set<int> 자동 추론
	var nums = {1, 2, 6, 2}; // 중복된 2 자동 삭제, 최종 {1,2,6}

	// 타입 혼합 시 Set<Object> 추론 (권장하지 않음, 타입 검증 손실)
	var mix = {1, "apple"};
}Code language: JavaScript (javascript)

타입 추론 후 다른 타입 요소를 넣으면 오류가 발생함

void main() {
  // 리터럴이 전부 문자열이므로 Set<String> 추론
  var animals = {'dog'};
  print(animals.runtimeType); // _CompactLinkedHashSet<String>

  // 같은 문자열 타입은 정상 추가 가능
  animals.add('cat');
  animals.add('pig');
  print(animals); // {dog, cat, pig}
  
  // 오류:add 메서드는 String을 요구하는데 int를 전달함
  animals.add(1); 
}Code language: Dart (dart)

2. 추가 삭제 및 길이

  • 단일 요소 추가:.add()
  • 일괄 추가:.addAll()
  • 요소 총 개수 얻기:.length
var elements = <String>{};
elements.add('fluorine');
elements.addAll({'chlorine', 'bromine'});
print(elements.length); //3Code language: PHP (php)

3. 상수 Set

리터럴 앞에 const를 붙이면 요소 추가/삭제 불가:

final constantSet = const {'fluorine', 'chlorine'};
// constantSet.add('helium'); // 오류 발생Code language: PHP (php)

4. Map 맵 (키값 쌍)

1. 기본 특징
  • Key-Value 쌍 데이터 저장;
  • Key 전역 유일,Value는 중복 가능;
  • Key, Value 어떤 객체 타입도 지원;
  • 리터럴 형식 {key: value}
  • 타입 자동 추론:
void main() {
	var gifts = {'first': 'partridge'}; // Map<String, String> 자동 추론
	
	var nobleGases = {2: 'helium'}; // Map<int, String> 자동 추론
}Code language: Dart (dart)
2. 두 가지 생성 방식
  • 리터럴 생성
var gifts = {'first': 'partridge'};  Code language: Dart (dart)
  • Map 생성자 생성 (new 키워드 생략 가능)
// 생성자 표기
var gifts = Map<String, String>();
gifts['first'] = 'partridge';Code language: JavaScript (javascript)
3. 추가, 조회, 길이
  1. 키값 추가/덮어쓰기:map[key] = value
  2. Key로 값 조회:map[key];Key 없으면 null 반환;
  3. 키값 쌍 총 개수:.length
var gifts = {'first': 'partridge'};
gifts['fourth'] = 'calling birds'; // 새로 추가
print(gifts['first']); //값 조회
print(gifts['fifth']);//존재하지 않는 키 조회
print(gifts.length); //쌍 개수 조회 Code language: PHP (php)
4. 상수 Map

리터럴 앞에 const 붙이면 키값 쌍 수정 불가:

final constantMap = const {2: 'helium', 10: 'neon'};
// constantMap[2] = 'Helium'; // 오류 발생Code language: Dart (dart)

5. 컬렉션 리터럴 확장 요소

컬렉션 리터럴 안에 여러 특수 문법 지원하며, 크게기본 단일 요소흐름 제어 요소 두 분류로 나뉘어 컬렉션 생성 코드를 간소화함.

  1. 기본 단일 요소:단일 표현식, Map 키값, 널 안전 요소
  2. 흐름 제어 요소:전개 연산자, if 조건, for 반복, 중첩 조합

1. 일반 표현식 요소

가장 기본적인 표기로 표현식을 직접 적고 계산 결과가 컬렉션에 삽입됨. 아래 예시 두 번째 요소는 2 * 3 연산 결과라 출력은 [1, 6, text]

void main() {
	var list = [1, 2 * 3, 'text'];
	print(list); //[1, 6, text]
}Code language: PHP (php)

2. 키값 요소

Map 리터럴 전용, 키표현식 : 값표현식 형식. 아래 예시 첫 요소의 키와 값 모두 표현식으로 계산됨.

void main() {
	var map = {1+1: 3*8, 'name': 'apple'};
	print(map); //{2: 24, name: apple}
}Code language: Dart (dart)

3. 널 안전 요소 (Dart ≥3.8)

문법 ?표현식:표현식 결과가 null이 아니어야 컬렉션에 삽입, null이면 무시

List 사용 예시: a는 null이므로 최종 삽입되지 않고 오류 없음

int? a = null;
int? b = 3;
var items = [1, ?a, ?b, 5]; // [1, 3, 5]Code language: JavaScript (javascript)

Map 사용 (key/value 둘 다 ? 붙일 수 있음)

String? k = null;
int? v = null;
var m = {?k: ?v}; // key 또는 value 하나라도 null이면 전체 키값 쌍 삭제
Code language: JavaScript (javascript)

4. Spread element 전개 연산자

① 일반 전개 ...

반복 가능한 컬렉션의 모든 요소를 펼쳐 삽입, null 컬렉션 전개 불가

var a = [1,2,3];
var items = [0, ...a, 4]; // [0,1,2,3,4]Code language: JavaScript (javascript)
② 널 안전 전개 ...?

null 허용 컬렉션 지원:컬렉션이 null이면 무시하고 오류 없음;

컬렉션 자체는 null이 아니어도 내부에 null 요소가 포함되면 null 유지

List<int>? a = null;
var b = [1, null, 3];
var items = [0, ...?a, ...?b, 4]; // [0, 1, null, 3, 4]Code language: PHP (php)

규칙:null을 허용하는 컬렉션은 반드시 ...? 사용해야 컴파일 오류가 발생하지 않습니다.

5. If element 조건 요소

컬렉션 안에 직접 if 분기 작성 가능, 조건 충족 시 해당 내용 삽입. 불린 판단, if-case 패턴 매칭, else 지원

기본 불린 판단
void main() {
	bool flag = true;
    var list = [0, if(flag) 1 else 99, 2];
	print(list); //[0, 1, 2]
}Code language: Dart (dart)
if-case 패턴 매칭 (타입/배열 분해)
void main() {
	Object data = 123;
	var info = [
	  if(data case int i) '숫자:$i',
	  if(data case String s) '텍스트:$s'
	];
	print(info); //[숫자:123]
}Code language: Dart (dart)

data가 int 타입이므로 ‘숫자:123’만 삽입되고 텍스트 쪽은 무시됩니다.

6. For element 반복 요소

컬렉션 내부에 for 반복문 직접 작성해 여러 요소 생성. for-in / 전통적인 3식 for 지원

var nums = [2,3,4];

// for-in
var list1 = [1, for(var n in nums) n*n, 7]; // [1,4,9,16,7]

// 3식 for
var list2 = [1, for(var x=5; x>2; x--) x, 7]; // [1,5,4,3,7]Code language: JavaScript (javascript)

7. 중첩 흐름 제어

if, for, 전개 연산자는 여러 단계로 자유롭게 중첩 가능, 다른 언어의 리스트 컴프리헨션과 동일한 효과

예시:짝수만 남기기

var numbers = [1,2,3,4,5,6];
var items = [
  0,
  for(var n in numbers)
    if(n.isEven) n,
  8
]; // [0,2,4,6,8]Code language: JavaScript (javascript)

예시:중첩 for + if + 전개 연산

void main() {
	var ys = [1,2,3];
	var nest = [
	  ...[
		for(var x=0;x<2;x++)
		  for(var y in ys)
			if(x<y) x+y*10
	  ]
	];
	print(nest); //[10, 20, 30, 21, 31]
}Code language: Dart (dart)

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다