맵
맵은 사전(dictionary)과 비슷하다. 예를 들어 people이란 단어에는 사람, baseball이라는 단어에는 야구라는 뜻이 부합되듯이 맵은 키(key)와 값(value)을 한 쌍으로 갖는 자료형이다.
키(key) | 값()value |
people | 사람 |
bassball | 야구 |
HashMap
put
put 메서드는 key와 value를 추가할 수 있다.
import java.util.HashMap;
public class Sample {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("people", "사람");
map.put("baseball", "야구");
}
}
get
get 메서드는 key에 해당하는 value를 얻을 때 사용한다.
import java.util.HashMap;
public class Sample {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("people", "사람");
map.put("baseball", "야구");
System.out.println(map.get("people")); // "사람" 출력
}
}
containsKey
containsKey 메서드는 맵에 해당 key가 있는지를 참(true) 또는 거짓(false)으로 리턴한다.
(... 생략 ...) HashMap<String, String> map = new HashMap<>();
map.put("people", "사람");
map.put("baseball", "야구");
System.out.println(map.containsKey("people")); // true 출력
true
remove
remove 메서드는 맵의 항목을 삭제하는 메서드로, 해당 key의 항목을 삭제한 후 value 값을 리턴한다.
(... 생략 ...)
HashMap<String, String> map = new HashMap<>();
map.put("people", "사람");
map.put("baseball", "야구");
System.out.println(map.remove("people")); // "사람" 출력
사람
size
size 메서드는 맵 요소의 개수를 리턴한다.
(... 생략 ...) HashMap<String, String> map = new HashMap<>();
map.put("people", "사람");
map.put("baseball", "야구");
System.out .println(map.remove(“people”)); // 사람 출력
System.out.println(map.size());
1
Keyset
keySet은 맵의 모든 key를 모아서 리턴한다.
import java.util.HashMap;
public class Sample {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("people", "사람");
map.put("baseball", "야구");
System.out.println(map.keySet()); // [baseball, people] 출력
}
}
[baseball, people]
집합
집합(Set) 자료형은 집합과 관련된 것을 쉽게 처리하기 위해 만든 것으로 HashSet, TreeSet, LinkedHashSet 등이 있다.
집합 자료형의 2가지 특징
- 중복을 허용하지 않는다.
- 순서가 없다(unordered).
교집합, 합집합, 차집합 구하기
예시 자료형
import java.util.Arrays;
import java.util.HashSet;
public class Sample { public static void main(String[] args) {
HashSet<Integer> s1 = new
HashSet<>(Arrays.asList(1, 2, 3, 4, 5, 6));
HashSet<Integer> s2 = new HashSet<>(Arrays.asList(4, 5, 6, 7, 8, 9));
}
}
교집합
retainAll 메서드를 이용하면 교집합을 쉽게 구할 수 있다.
import java.util.Arrays;
import java.util.HashSet;
public class Sample {
public static void main(String[] args) {
HashSet<Integer> s1 = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5, 6));
HashSet<Integer> s2 = new HashSet<>(Arrays.asList(4, 5, 6, 7, 8, 9));
HashSet<Integer> intersection = new HashSet<>(s1); // s1으로 intersection 생성
intersection.retainAll(s2); // 교집합 수행
System.out.println(intersection); // [4, 5, 6] 출력
}
}
[4, 5, 6]
합집합
합집합은 addAll 메서드를 사용한다.
import java.util.Arrays;
import java.util.HashSet;
public class Sample { public static void main(String[] args) {
HashSet<Integer> s1 = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5, 6));
HashSet<Integer> s2 = new HashSet<>(Arrays.asList(4, 5, 6, 7, 8, 9));
HashSet<Integer> union = new HashSet<>(s1); // s1으로 union 생성
union.addAll(s2); // 합집합 수행 System.out.println(union); // [1, 2, 3, 4, 5, 6, 7, 8, 9] 출력
}
}
[1, 2, 3, 4, 5, 6, 7, 8, 9]
차집합
차집합은 removeAll 메서드를 사용한다.
import java.util.Arrays;
import java.util.HashSet;
public class Sample { public static void main(String[] args) {
HashSet<Integer> s1 = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5, 6));
HashSet<Integer> s2 = new HashSet<>(Arrays.asList(4, 5, 6, 7, 8, 9));
HashSet<Integer> substract = new HashSet<>(s1); // s1으로 substract 생성
substract.removeAll(s2); // 차집합 수행
System.out.println(substract); // [1, 2, 3] 출력
}
}
[1, 2, 3]
집합 자료형과 관련된 메서드
add
add 메서드는 집합 자료형에 값을 추가할 때 사용한다.
import java.util.HashSet;
public class Sample {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("Jump");
set.add("To");
set.add("Java");
System.out.println(set); // [Java, To, Jump] 출력
}
}
[Java, To, Jump]
addAll
값을 한꺼번에 여러 개 추가할 때는 addAll 메서드를 사용한다.
import java.util.Arrays;
import java.util.HashSet;
public class Sample {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("Jump");
set.addAll(Arrays.asList("To", "Java"));
System.out.println(set); // [Java, To, Jump] 출력
}
}
[Java, To, Jump]
remove
remove 메서드는 특정 값을 제거할 때 사용한다.
import java.util.Arrays;
import java.util.HashSet;
public class Sample {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>(Arrays.asList("Jump", "To", "Java"));
set.remove("To");
System.out.println(set); // [Java, Jump] 출력
}
}
[Java, Jump]
상수 집합
enum 자료형은 서로 연관 있는 여러 개의 상수 집합을 정의할 때 사용한다.
enum CoffeeType {
AMERICANO,
ICE_AMERICANO,
CAFE_LATTE
};
이렇게 정의한 상수 집합은 다음과 같이 사용할 수 있다.
public class Sample {
enum CoffeeType {
AMERICANO,
ICE_AMERICANO,
CAFE_LATTE }
;
public static void main(String[] args) {
System.out.println(CoffeeType.AMERICANO); // AMERICANO 출력 System.out.println(CoffeeType.ICE_AMERICANO); // ICE_AMERICANO 출력 System.out.println(CoffeeType.CAFE_LATTE); // CAFE_LATTE 출력
}
}
AMERICANO
ICE_AMERICANO
CAFE_LATTE
또는 반복문에서 사용할 수도 있다.
public class Sample {
enum CoffeeType {
AMERICANO,
ICE_AMERICANO,
CAFE_LATTE
};
public static void main(String[] args) {
for(CoffeeType type: CoffeeType.values()) {
System.out.println(type); // 순서대로 AMERICANO, ICE_AMERICANO, CAFE_LATTE 출력
}
}
}
AMERICANO
ICE_AMERICANO
CAFE_LATTE
형 변환과 final
형 변환
String num = "123";
자료형은 문자열이지만 그 내용은 숫자로 이루어진 값이다. 이런 경우에 문자열을 정수(integer)로 바꿀 수 있다. 문자열을 정수로 바꾸려면 Integer 클래스를 사용한다.
public class Sample {
public static void main(String[] args) {
String num = "123"; int n = Integer.parseInt(num);
System.out.println(n); // 123 출력
}
}
123
정수를 문자열로 바꾸는 가장 쉬운 방법은 정수 앞에 빈 문자열("")을 더해 주는 것이다.
public class Sample { public static void main(String[] args) { int n = 123; String num = "" + n; System.out.println(num); // 123 출력 } }
123
또는 다음과 같이 변환할 수 있다.
public class Sample {
public static void main(String[] args) {
int n = 123;
String num1 = String.valueOf(n);
String num2 = Integer.toString(n);
System.out.println(num1); // 123 출력 System.out.println(num2); // 123 출력
}
}
123
123
String.valueOf(정수), Integer.toString(정수) 모두 정수를 문자열로 바꾸어 리턴한다.
그리고 소수점이 포함되어 있는 숫자 형태의 문자열은 같은 방법으로 Double.parseDouble이나 Float.parseFloat를 사용해 형 변환할 수 있다.
public class Sample {
public static void main(String[] args) {
String num = "123.456";
double d = Double.parseDouble(num);
System.out.println(d);
}
}
123.456
자주 사용하지는 않지만 정수와 실수 사이의 형 변환도 가능하다.
public class Sample {
public static void main(String[] args) {
int n1 = 123;
double d1 = n1; // 정수를 실수로 바꿀때에는 캐스팅이 필요없다.
System.out.println(d1); // 123.0 출력
double d2 = 123.456;
int n2 = (int) d2; // 실수를 정수로 바꿀때에는 반드시 정수형으로 캐스팅해 주어야 한다.
System.out.println(n2); // 소숫점이 생략된 123 출력
}
}
123.0
123
그리고 실수 형태의 문자열을 정수로 바꿀 때는 NumberFormatException이 발생하므로 주의해야 한다.
final
final은 자료형에 값을 단 한 번만 설정할 수 있게 강제하는 키워드이다. 값을 한 번 설정하면 그 값을 다시 설정할 수 없다.
public class Sample {
public static void main(String[] args) {
final int n = 123; // final로 설정하면 값을 바꿀 수 없다.
n = 456; // 컴파일 오류 발생
}
}
리스트의 경우도 final로 선언하면 재할당은 불가능하다.
import java.util.ArrayList;
import java.util.Arrays;
public class Sample {
public static void main(String[] args) {
final ArrayList<String> a = new ArrayList<>(Arrays.asList("a", "b"));
a = new ArrayList<>(Arrays.asList("c", "d")); // 컴파일 에러 발생
}
}
그러므로 final은 프로그램을 수행하면서 그 값이 바뀌면 안 될 때 사용한다.
퀴즈
- 다음 중 HashMap의 특징은? (정답:c)
(a) 순서를 보장한다.
(b) 키가 중복될 수 있다.
(c) null 키를 허용한다.
(d) 동기화되어 있다.
- Map에서 키-값 쌍을 추가할 때 사용하는 메서드는? (정답:a)
(a) put()
(b) add()
(c) insert()
(d) addEntry()
- 다음 코드의 출력 결과는 무엇인가? (정답:b)
Map<String, Integer> map = new HashMap<>();
map.put("Java", 8);
map.put("Python", 3);
System.out.println(map.get("Java"));
(a) 3
(b) 6
(c) null
(d) Error
- Map에 키가 존재하는지 여부를 알 수 있는 메서드는? (정답:d)
(a) get()
(b) isEmpty()
(c) containsValue()
(d) containsKe
서술형 문제
- Java의 Set 인터페이스를 사용하는 목적에 대해 서술하시오.
중복된 요소를 자동으로 제거한다, 특정 요소가 존재하는지 확인할 수 있다.
- 형 변환(타입 캐스팅)의 개념을 설명하고, 자바에서의 자동 형 변환과 수동 형 변환의 차이점을 서술하시오.
형변환(Type Casting)이란 변수의 타입을 변화시킨다는 의미이고 형변환을 하게되면 특정 자료형의 값을 다른 자료형의 변수에 대입할 수 있게 된다. 자동 형 변환은 작은 데이터 타입에서 큰 데이터 타입으로 변환할 때 자바가 자동으로 처리하고 수동 형변환은 큰 데이터 타입에서 작은 데이터 타입으로 변환할 때는 데이터 손실이 발생할 수 있으므로 개발자가 명시적으로 형 변환을 수행해야한다.
- Java의 final 키워드에 대해 설명하고, final 변수를 사용할 때의 장점을 서술하시오.
final은 변수를 한 번만 초기화할 수 있음을 보장하는 역할을 한다. 안전성이 높고 성능 최적화를 유지할 수 있다.
- 형 변환 시 발생할 수 있는 예외 상황에 대해 설명하고, ClassCastException이 발생하는 경우를 예로 들어 설명하시오.
객체의 실제 타입과 캐스팅하려는 타입이 호환되지 않을 때 발생한다.
코딩 테스트 문제
- 완주하지 못한 선수
- 숫자 문자열과 영단어
if 문
조건을 판단하여 해당 조건에 맞는 상황을 수행하는 데 쓰이는 것이 바로 if 문이다.
boolean money = true;
if (money) {
System.out.println("택시를 타고 가라");
}else {
System.out.println("걸어가라"); }
if 문과 else 문의 기본 구조
if 문은 주어진 조건이 참일 때 실행되는 코드 블록이고, else 문은 if 문의 조건이 거짓일 때 실행되는 코드 블록이다.
if (조건문) {
<수행할 문장1>;
<수행할 문장2>;
...
} else {
<수행할 문장A>;
<수행할 문장B>;
...
}
비교 연산자
비교 연산자 | 설명 |
x < y | x가 y보다 작다 |
x > y | x가 y보다 크다 |
x == y | x와 y가 같다 |
x != y | x와 y가 같지 않다 |
x >= y | x가 y보다 크거나 같다 |
x <= y | x가 y보다 작거나 같다 |
and, or, not 연산자
연산자 | 설명 |
x && y | x와 y 모두 참이어야 참이다 |
x || y | x와 y 둘 중 적어도 하나가 참이면 참이다 |
!x | x가 거짓이면 참이다 |
contains
대상 문자열에 특정 문자열이 포함되어 있는지 확인하는 함수이다.
else if
if, else if, else의 기본 구조는 다음과 같다.
if (조건문) {
<수행할 문장1>
<수행할 문장2>
...
}else if (조건문) {
<수행할 문장1>
<수행할 문장2>
...
}else if (조건문) {
<수행할 문장1>
<수행할 문장2>
...
...
} else {
<수행할 문장1>
<수행할 문장2>
...
}
switch/case 문
switch/case 문의 구조는 다음과 같다.
switch(입력변수)
{ case 입력값1: ...
break; case 입력값2: ...
break;
...
default: ...
break;
}
입력 변수의 값과 일치하는 case 입력값(입력값1, 입력값2, …)이 있다면 해당 case 문에 속한 문장들이 실행된다. case 문마다 break라는 문장이 있는데 해당 case 문을 실행한 뒤 switch 문을 빠져나가기 위한 것이다. 만약 break 문이 빠져 있다면 그 다음의 case 문에 속한 문장들이 실행된다.
while 문
while 문의 기본 구조
while (조건문) {
<수행할 문장1>;
<수행할 문장2>;
<수행할 문장3>;
...
}
조건문이 참인 동안 while 문이 수행할 문장들을 반복하여 수행한다.
e 문이 수행할 문장들을 반복하여 수행한다.
for 문
for 문의 기본 구조
for (초기치; 조건문; 증가치) {
...
}
이중 for 문
for 문을 두 번 사용하면 아주 간단하게 구구단을 출력할 수 있다.
for(int i=2; i<10; i++) {
for(int j=1; j<10; j++) {
System.out.print(i*j+" ");
}
System.out.println(""); // 줄을 바꾸어 출력하는 역할을 한다.
}
2 4 6 8 10 12 14 16 18 3 6 9 12 15 18 21 24 27 4 8 12 16 20 24 28 32 36 5 10 15 20 25 30 35 40 45 6 12 18 24 30 36 42 48 54 7 14 21 28 35 42 49 56 63 8 16 24 32 40 48 56 64 72 9 18 27 36 45 54 63 72 81
for each 문
for each 문은 J2SE 5.0부터 추가되었다. for each라는 키워드가 따로 있는 것은 아니고 앞서 배운 for 문을 이용한다. 하지만 조건문의 문법이 조금 다르다.
String[] numbers = {"one", "two", "three"};
for(int i=0; i<numbers.length; i++) {
System.out.println(numbers[i]);
}
one two three
퀴즈
- 다음 코드의 출력 결과는 무엇인가?(정답:a)
int num = 10;
if (num > 5) {
System.out.println("A");
} else {
System.out.println("B");
}
a) A
b) B
c) A와 B 모두
d) 아무 것도 출력되지 않음
다음 중 if 문의 올바른 사용법은? (정답:b)
a)
if x > 10 {
System.out.println("x는 10보다 큽니다.");
}
b)
if (x > 10)
System.out.println("x는 10보다 큽니다.");
c)
if x > 10 then
System.out.println("x는 10보다 큽니다.");
d)
if [x > 10] {
System.out.println("x는 10보다 큽니다.");
}
- 다음 중 중첩 if 문의 예는?(정답:a)
if (a > b)
if (b > c)
System.out.println("a > b > c");
b)
if (a > b) {
System.out.println("a > b");
}
if (b > c) {
System.out.println("b > c");
}
c)
if (a > b) else {
System.out.println("a <= b");
}
d)
if (a > b) System.out.println("a > b"); else System.out.println("a <= b");
- 다음 if-else if-else 구조에서 result의 값은 무엇인가?(정답:b)
int score = 85;
String result;
if (score >= 90) {
result = "A";
} else if (score >= 80) {
result = "B";
} else {
result = "C";
a) A
b) B
c) C
d) 오류 발생
- 다음 if 문에서 논리 오류가 있는 것은?(정답:a)
a)
if (x = 10) {
System.out.println("x는 10입니다.");
}
b)
if (x == 10) {
System.out.println("x는 10입니다.");
}
c)
if (x > 5 && x < 15) {
System.out.println("x는 5보다 크고 15보다 작습니다.");
}
d)
if (x != 0) {
System.out.println("x는 0이 아닙니다.");
}
- 다음 코드의 출력 결과는 무엇인가? (정답:c)
int day = 3;
switch (day) {
case 1:
System.out.println("Monday");
break;
case 2:
System.out.println("Tuesday");
break;
case 3:
System.out.println("Wednesday");
break;
default:
System.out.println("Invalid day");
}
a) Monday
b) Tuesday
c) Wednesday
d) Invalid day
- switch 문에서 break 문을 생략하면 어떤 결과가 발생하는가?(정답:c)
a) 컴파일 오류가 발생한다.
b) 해당 case의 코드만 실행된다.
c) 다음 case의 코드도 연속적으로 실행된다.
d) default 블록이 무조건 실행된다.
- 다음 중 switch 문의 올바른 사용 예를 2가지 고르시오. (정답:b,c)
a)
switch (x > 10) {
case true:
System.out.println("x는 10보다 큽니다.");
break;
case false:
System.out.println("x는 10보다 작거나 같습니다.");
break;
}
b)
switch (day) {
case "Monday":
System.out.println("Today is Monday");
break;
case "Tuesday":
System.out.println("Today is Tuesday");
break;
}
c)
switch (x) {
case 1:
System.out.println("One");
break;
case 2:
System.out.println("Two");
break;
default:
System.out.println("Other");
}
d)
switch (3.14) {
case 3.14:
System.out.println("Pi");
break;
default:
System.out.println("Unknown");
}
- 다음 코드의 출력 결과는 무엇인가? (정답:a)
char grade = 'B';
switch (grade) {
case 'A':
System.out.println("Excellent");
break;
case 'B':
System.out.println("Good");
case 'C':
System.out.println("Fair");
break;
default:
System.out.println("Poor");
}
a) Good
Fair
b) Good
c) Excellent
d) Fair
- 다음 코드의 출력 결과는 무엇인가? (정답:a)
for (int i = 0; i < 3; i++) {
System.out.print(i + " ");
}
a) 0 1 2
b) 1 2 3
c) 0 1 2 3
d) 1 2
- 다음 중 무한 루프를 생성하는 for 문의 예는? (정답:b,d)
a)
for (int i = 0; i < 10; i++) {}
b)
for (; ;) {}
c)
for (int i = 0; i != 10; i += 2) {}
d)
for (int i = 0; i <= 10; i--) {}
- 다음 코드의 출력 결과는 무엇인가? (정답:a)
for (int i = 5; i > 0; i--) {
if (i == 3) {
break;
}
System.out.print(i + " ");
}
a) 5 4
b) 5 4 3
c) 5 4 2 1
d) 5 4 3 2 1
- 다음 중 for 문을 사용하여 1부터 10까지의 합을 구하는 올바른 코드는? (정답:a)
a)
int sum = 0;
for (int i = 1; i <= 10; i++) {
sum += i;
}
System.out.println(sum);
b)
int sum = 0;
for (int i = 1; i < 10; i++) {
sum += i;
}
System.out.println(sum);
c)
int sum = 0;
for (int i = 0; i <= 10; i++) {
sum += i;
}
System.out.println(sum);
d) 모두 올바르지 않음
- 다음 코드의 출력 결과는 무엇인가? (정답:b)
for (int i = 0; i < 5; i++) {
if (i == 2) {
continue;
}
System.out.print(i + " ");
}
a) 0 1 2 3 4
b) 0 1 3 4
c) 1 2 3 4
d) 0 1 2 4
- 다음 코드의 출력 결과는 무엇인가? (정답:a)
int i = 1;
while (i <= 3) {
System.out.print(i + " ");
i++;
}
a) 1 2 3
b) 1 2 3 4
c) 0 1 2
d) 2 3 4
- 다음 중 무한 루프를 생성하는 while 문의 예는? (정답:a)
a)
while (true) {}
b)
while (false) {}
c)
while (x < 10) {
x++;
}
d)
while (x > 10) {
x--;
}
- 다음 코드의 출력 결과는 무엇인가? (정답:b)
int count = 0;
while (count < 5) {
if (count == 3) {
count++;
continue;
}
System.out.print(count + " ");
count++;
}
a) 0 1 2 3 4
b) 0 1 2 4
c) 0 1 2 3
d) 0 1 2 4 5
- 다음 중 while 문을 사용하여 1부터 10까지의 홀수를 출력하는 올바른 코드는? (정답:a,c)
a)
int i = 1;
while (i <= 10) {
if (i % 2 != 0) {
System.out.print(i + " ");
}
i++;
}
b)
int i = 0;
while (i < 10) {
if (i % 2 == 0) {
System.out.print(i + " ");
}
i++;
}
c)
int i = 1;
while (i < 10) {
System.out.print(i + " ");
i += 2;
}
d) a와 c 모두 올바르다.
- 다음 코드의 출력 결과는 무엇인가? (정답:b)
int i = 0;
while (i < 3) {
System.out.print(i + " ");
i += 2;
}
a) 0 1 2
b) 0 2
c) 0 2 4
d) 1 3
- 다음 코드의 출력 결과는 무엇인가? (정답:a)
int[] numbers = {1, 2, 3, 4, 5};
for (int num : numbers) {
System.out.print(num + " ");
}
a) 1 2 3 4 5
b) 0 1 2 3 4
c) 1 2 3 4
d) 2 3 4 5
- 다음 중 for-each 문을 사용하는 이유로 옳지 않은 것은? (정답:c)
a) 배열이나 컬렉션의 모든 요소를 간편하게 순회하기 위해
b) 인덱스 관리를 자동으로 해주기 위해
c) 요소를 수정할 수 있기 위해
d) 코드의 가독성을 높이기 위해
- 다음 코드의 출력 결과는 무엇인가? (정답:a)
String[] fruits = {"Apple", "Banana", "Cherry"};
for (String fruit : fruits) {
System.out.print(fruit.charAt(0) + " ");
}
a) A B C
b) Apple Banana Cherry
c) 65 66 67
d) A p C
- 다음 중 for-each 문을 사용하여 리스트의 모든 요소를 출력하는 올바른 코드는? (정답:d)
a)
List<String> list = Arrays.asList("Java", "Python", "C++");
for (int i : list) {
System.out.println(i);
}
b)
List<String> list = Arrays.asList("Java", "Python", "C++");
for (String lang : list) {
System.out.println(lang);
}
c)
List<String> list = Arrays.asList("Java", "Python", "C++");
for (Object obj : list) {
System.out.println(obj);
}
d) b와 c 모두 올바르다.
- 다음 코드의 출력 결과는 무엇인가? (정답:b)
int[] numbers = {2, 4, 6, 8};
int sum = 0;
for (int num : numbers) {
sum += num;
}
System.out.println(sum);
a) 10
b) 20
c) 15
d) 0
코딩 테스트 문제
- 배열 회전시키기
- 콜라츠 추측 :
'WINK-(Web & App) > JAVA 스터디' 카테고리의 다른 글
[2024-2 Java 스터디] 김민서 #3주차 (1) | 2024.10.30 |
---|---|
[2024-2 Java 스터디] 정채은 #2주차 (0) | 2024.10.18 |
[2024-2 Java 스터디] 김재승 #2주차 (0) | 2024.10.17 |
[2024-2 Java 스터디] 강보경 #2주차 (5) | 2024.10.16 |
[2024-2 Java 스터디] 이서영 #2주차 (1) | 2024.10.16 |