배열과 collection
배열의 장점과 단점은
장점 : 복수의 데이터를 하나의 이름으로 처리(index 접근)
단점 : 배열의 크기 조정 불가하고 타입이 고정적이다
하지만 collection은 size가 가변적이고 타입에 자유롭기 때문에
리스트를 사용하면 자료 추가와 수정이 용이하다
종류: List(순서 O,중복 O), Set(순서 X, 중복 X) ,
Map(순서{key:X, value: X}/중복{key: X value: O}) + Hash, Tree
List
특징: 순서가 있고, 중복이 가능하다
Member라는 클래스를 생성하여 List 안에 Member를 추가해주려고 한다
class Member{
private String id;
private String pass;
private String name;
public Member(String id, String pass, String name) {
this.id = id;
this.pass = pass;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//Ctrl+o 사용하면 자동생성 가능
@Override
public String toString() {
return String.format("%s(ID : %s)",name,id);
}
메인 메소드에서 List list = new ArrayList()를 생성해서
새로운 리스트를 하나 만들어준다
public class Ex01List {
public static void main(String[] args) {
List list = new ArrayList();
ist<Member> list2 = new ArrayList(); //Member type 만 받음 :: 제네릭스
list.add(new Member("hgd","1","홍길동"));
list.add(new Member("kgd","2","김길동"));
list.add(new Member("jgd","3","정길동"));
}
}
다음과 같이 리스트안에 쉽게 값을 추가 하는 것이 가능함
list를 출력하는 방법
System.out.println(list);
list 안의 특정 원소를 출력하는 방법
System.out.println(list.get(0));
ArrayList()와 LinkedList() 의 차이
ArrayList와 LinkedList는 Java의 List 인터페이스를 구현한 두 가지 주요 클래스입니다.
이 둘은 데이터를 저장하고 관리하는 방식이 다르며, 각기 다른 성능 특성과 사용 사례를 가집니다
1. 데이터 저장 방식
- ArrayList:
- 내부적으로 배열을 사용하여 데이터를 저장합니다.
- 인덱스를 통해 요소에 접근할 수 있습니다.
- 배열의 크기를 동적으로 조절할 수 있지만, 크기를 늘릴 때는 새로운 배열을 생성하고 기존 요소를 복사하는 작업이 필요합니다.
- LinkedList:
- 이중 연결 리스트(doubly linked list) 구조를 사용합니다.
- 각 요소는 노드로 표현되며, 노드는 데이터와 다음 및 이전 노드에 대한 참조를 포함합니다.
- 요소 접근은 노드를 따라 순차적으로 이루어집니다.
2. 성능 차이
- 접근 시간:
- ArrayList: 인덱스를 통해 상수 시간 O(1)에 요소에 접근할 수 있습니다.
- LinkedList: 인덱스로 접근할 때는 첫 번째 노드부터 순차적으로 접근해야 하므로 평균적으로 O(n/2) 시간이 소요됩니다. 최악의 경우 O(n) 시간이 소요됩니다.
- 삽입 및 삭제 시간:
- ArrayList:
- 요소를 배열의 끝에 추가하는 것은 평균적으로 상수 시간 O(1)이지만, 배열의 크기를 늘려야 하는 경우 O(n) 시간이 걸릴 수 있습니다.
- 중간에 요소를 삽입하거나 삭제하는 경우, 배열의 나머지 요소를 이동시켜야 하므로 O(n) 시간이 소요됩니다.
- LinkedList:
- 첫 번째나 마지막 요소를 추가하거나 삭제하는 것은 상수 시간 O(1)에 수행됩니다.
- 중간 요소의 삽입이나 삭제도 해당 위치까지 순차적으로 접근하는 시간 O(n)과 함께 상수 시간 O(1)로 수행됩니다.
- ArrayList:
3. 메모리 사용
- ArrayList:
- 요소만을 저장하며, 추가적인 객체나 참조를 저장하지 않습니다.
- 크기를 조절할 때 새로운 배열을 생성하고 기존 요소를 복사해야 하므로 일시적으로 더 많은 메모리를 사용할 수 있습니다.
- LinkedList:
- 각 요소가 데이터와 함께 두 개의 참조(다음 노드와 이전 노드)를 저장해야 하므로, 추가적인 메모리 오버헤드가 있습니다.
4. 기타 기능
- ArrayList:
- RandomAccess 인터페이스를 구현하여, 임의 접근이 빠릅니다.
- Serializable과 Cloneable 인터페이스를 구현합니다.
- LinkedList:
- Deque 인터페이스를 구현하여, 큐(queue) 및 덱(deque)로 사용될 수 있습니다.
- Serializable과 Cloneable 인터페이스를 구현합니다.
사용 예시
- ArrayList:
- 데이터를 자주 읽고 접근해야 하는 경우에 적합합니다. (예: 인덱스를 통해 요소를 빈번히 읽는 경우)
- 배열의 크기를 미리 예측할 수 있는 경우에 유리합니다.
- LinkedList:
- 삽입과 삭제가 빈번히 발생하는 경우에 적합합니다. (예: 큐, 스택, 덱 구현)
- 요소의 순차적인 접근이 주로 이루어지는 경우에 유리합니다.
List linkedList = new LinkedList();
- **ArrayList**는 빠른 임의 접근이 필요한 경우에 유리하며, 데이터의 크기가 자주 변하지 않을 때 적합합니다.
- **LinkedList**는 빈번한 삽입과 삭제 작업이 필요할 때 유리하며, 큐나 스택과 같은 자료 구조를 구현할 때 적합합니다.
for문을 사용해서 리스트 출력하기
public class Ex01List {
public static void main(String[] args) {
List list = new ArrayList();
List<Member> list2 = new ArrayList(); //Member type 만 받음 :: 제네릭스
list.add(new Member("hgd","1","홍길동"));
list.add(new Member("kgd","2","김길동"));
list.add(new Member("jgd","3","정길동"));
System.out.println(list);
//1.for index
for (int i=0; i<list.size(); i++) {
System.out.println(list.get(i));
Utils.typeOf(list.get(i));
}
//2.enhanced for
for(Object o : list){
System.out.println(o);
Utils.typeOf(o);
}
}
}
Iterator
Iterator it = list.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
Consumer
java.util.function 패키지에 속해 있다
Consumer는 입력 매개변수를 받아서 어떤 동작을 수행하지만,
결과를 반환하지 않는 함수형 인터페이스를 말한다
//03. foreach -1
//익명객체는 일회성이고 참조할 일이 없는 경우에 사용한다
list.forEach(new Consumer() {
@Override
public void accept(Object o) {
System.out.println("forEach: "+o);
Utils.typeOf(o);
}
});
//03. foreach -2 , 람다식
list.forEach(o->{
System.out.println("람다식: "+o);
Utils.typeOf(o); });
//03. foreach -3
//클래스를 생성해야하는 경우, 참조 할 경우가 있을 경우
class ObjConsumer implements Consumer{
String lists="";
@Override
public void accept(Object o) {
list+=o;
System.out.println("forEach: "+o);
Utils.typeOf(o);
}
}
ObjConsumer oc = new ObjConsumer();
list.forEach(oc); //list.forEach(Consumer consumer)
System.out.println(oc.lists);
}
데이터 리스트 삭제하기
list.clear();
리스트 안에 포함되어있는지 확인하는 방법 list.contains()
System.out.println( list.contains(10));
list.addAll(new ArrayList(5));
리스트가 비어있는지 확인하기
System.out.println(list.isEmpty());
ArrayList 처리시간 과 LinkedList 처리시간 확인하기
package p07_Collection;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class Ex02LinkedList {
public static void main(String[] args) {
List al = new ArrayList();
List ll = new LinkedList();
System.out.println("==== 순차적 추가 ====");
System.out.println("ArrayList: "+addSequentially(al));
System.out.println("LinkedList: "+addSequentially(ll));
System.out.println("==== 중간에 추가 ====");
System.out.println("ArrayList: "+addMiddle(al));
System.out.println("LinkedList: "+addMiddle(ll));
System.out.println("==== 중간 삭제 ====");
System.out.println("ArrayList: "+removeMiddle(al));
System.out.println("LinkedList: "+removeMiddle(ll));
System.out.println("==== 순차 삭제 ====");
System.out.println("ArrayList: "+removeSequentially(al));
System.out.println("LinkedList: "+removeSequentially(ll));
}
private static long addSequentially(List list){
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
list.add(i+"");
}
long end = System.currentTimeMillis();
return end - start;
}
private static long addMiddle(List list){
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
list.add(5000,i+"");
}
long end = System.currentTimeMillis();
return end - start;
}
private static long removeSequentially(List<String> list){
long start = System.currentTimeMillis();
for (int i = list.size()-1; i >=0; i--) {
list.remove(i);
}
long end = System.currentTimeMillis();
return end - start;
}
private static long removeMiddle(List<String> list){
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
list.remove(i);
}
long end = System.currentTimeMillis();
return end - start;
}
}
Arrays : Collection에 배열을 다루기 위해 추가된 클래스
package p07_Collection;
import java.util.Arrays;
public class Ex03Arrays {
public static void main(String[] args) {
int[]arr ={0,1,2,3,4};
int []arr2 = Arrays.copyOf(arr, arr.length);
int []arr3 = Arrays.copyOfRange(arr, 2,4);
System.out.println(Arrays.toString(arr));
System.out.println(Arrays.toString(arr2));
System.out.println(Arrays.toString(arr3));
}
}
int []arr4 = new int[5];
Arrays.fill(arr4, 10);
System.out.println(Arrays.toString(arr4));
Arrays.setAll(arr4, new IntUnaryOperator() {
@Override
public int applyAsInt(int operand) {
return (int)(Math.random()*5);
}
});
Arrays.sort(arr4);
System.out.println(Arrays.toString(arr4));
int idx = Arrays.binarySearch(arr4,2);
System.out.println(idx);
int[][] arr20={{11,12},{21,22}};
System.out.println(Arrays.toString(arr20));
System.out.println(Arrays.deepToString(arr20));
//배열을 List로 변환
Integer [] arrInt1 = new Integer[]{0,1,2,3};
List<Integer> list = new ArrayList<>(Arrays.asList(arrInt1));
//list를 배열로
Integer [] arrInt2 = list.toArray(new Integer[arrInt1.length]);
System.out.println(Arrays.toString(arrInt2));
Integer[]arrInt3 = list.stream().toArray(value -> new Integer[value]);
System.out.println(Arrays.toString(arrInt3));
Stack
public class Ex04StackQueue {
public static void main(String[] args) {
Stack stack = new Stack();
stack.push(0);stack.push(1); stack.push(2);
System.out.println(stack);
System.out.println(stack.size());
System.out.println(stack.contains(1));
}
}
System.out.println(stack.pop());
System.out.println(stack);
System.out.println(stack.push(4));
System.out.println(stack);
System.out.println(stack.peek());
System.out.println(stack);
Queue q= new LinkedList();
q.offer("a"); q.offer("b"); q.offer("c");
System.out.println(q);
System.out.println(q.poll());
System.out.println(q.peek());
System.out.println(q);
Colloection - Vector
Collection 이전에 나온 버전(동기화 포함)
Vector v = new Vector();
v.add(0);
v.add("a");
v.add(true);
Enumeration e = v.elements();
while (e.hasMoreElements()){
System.out.println(e.nextElement());
}
e = v.elements(); //다시 사용하려고 할 때
Iterator it = v.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
it = v.iterator();//다시 사용하려고 할 때
Set
Set 선언하는 방법과 특징은 Set은 순서와 중복이 없다
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class Ex05Set {
public static void main(String[] args) {
Set set = new HashSet();
set.add(4); set.add(4);
set.add(2); set.add(3);
System.out.println(set);
}
}
set.add(1); set.remove(4);
System.out.println(set);
for (int i : set) {
//unboxing
System.out.println(i);
Iterator it = set.iterator();
while (it.hasNext()) System.out.println(it.next());
}
package p07_Collection;
import com.sun.security.jgss.GSSUtil;
import java.util.*;
public class Ex05Set {
public static void main(String[] args) {
Set<Integer> set = new HashSet(); //boxing
set.add(4); set.add(4);
set.add(2); set.add(3);
System.out.println(set);
set.add(1); set.remove(4);
System.out.println("Set1: "+set);
for (int i : set) {
//unboxing
System.out.println(i);
}
Iterator it = set.iterator();
while (it.hasNext()) System.out.println(it.next());
System.out.println("------------------");
Lotto lotto = new Lotto();
lotto.Start();
System.out.println("------------------");
Set<Integer> lotto2 = new HashSet<>();
while(lotto2.size()<6){
lotto2.add((int)(Math.random()*45)+1);
}
ArrayList list3 = new ArrayList(lotto2);
Collections.sort(list3);
System.out.println(list3);
//정렬이 되어서 나옴
Set<Integer> lotto3 = new TreeSet<>();
while (lotto2.size() <6 ){
lotto2.add((int)(Math.random()*45)+1);
}
System.out.println(lotto3);
}
}
class Lotto{
void Start(){
Set<Integer> number = new HashSet();
while(number.size()<7)
{
int randomNum = (int)(Math.random()*(42)+1);
if(!number.contains(randomNum)){
number.add(randomNum);
if(number.size() == 7){
System.out.printf("보너스 : %d \n",randomNum);
}
else{
System.out.printf("당첨번호 : %d \n",randomNum);
}
}
}
System.out.println(number);
}
}
package p07_Collection;
import java.util.HashSet;
import java.util.Set;
public class Ex06Setequals {
public static void main(String[] args) {
Set set = new HashSet();
set.add(new Person("LGH", "user1"));
set.add(new Person("LGH", "user1"));
System.out.println(set);
}
}
class Person{
String name, id;
public Person(String name, String id)
{
this.name=name;
this.id =id;
}
}
new 연산자에 의해서 Hash 주소값이 다르게 들어간다
이 같은 값이 들어가는 경우, 같은 hashCode로 취급해 주기 위해서 다음 hashCode를 비교해주어야 한다
class Person{
String name, id;
public Person(String name, String id)
{
this.name=name;
this.id =id;
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Person) {
Person p = (Person) obj;
return name.equals(p.name)&&id.equals(p.id);
}
return false;
}
}
instanceof는 객체가 특정 클래스 또는 인터페이스의 인스턴스인지
여부를 확인하기 위해 사용되는 연산자이다
@Override
public boolean equals(Object obj) {
if(obj instanceof Person) {
Person p = (Person) obj;
return name.equals(p.name)&&id.equals(p.id);
}
return false;
}
instanceof를 사용하는 이유는
1. 타입 검사
if (obj instanceof String) {
// obj는 String 타입입니다.
}
2. 안전한 타입 캐스팅
if (obj instanceof String) {
String str = (String) obj;
// 이제 안전하게 str을 사용할 수 있습니다.
}
3. 다형성과 유연성
public void process(Object obj) {
if (obj instanceof String) {
// String 타입에 대한 처리
} else if (obj instanceof Integer) {
// Integer 타입에 대한 처리
} else if (obj instanceof MyCustomClass) {
// MyCustomClass 타입에 대한 처리
}
}
4. 인터페이스 구현 확인
if (obj instanceof MyInterface) {
MyInterface myInterface = (MyInterface) obj;
// 이제 myInterface를 사용하여 인터페이스 메서드를 호출할 수 있습니다.
}
TreeSet
TreeSet은 정렬되는 기능을 가지고 정렬될 수 있는 값들만 받는다
class Ball implements Comparable {
private int num;
public Ball(int num) {
this.num = num;
}
@Override
public int compareTo(Object o) {
if(o instanceof Ball){
Ball b = (Ball)o;
//뺄 때 0 같다. 음수 작다, 양수 크다
return num-b.num; //순차 정렬
//return -(num-b.num); //역정렬
}
return 0;
}
@Override
public String toString() {
return num+" ";
}
}
메서드를 재정의 하고 다른 곳에서 사용하기 위해서 인터페이스화 해주어야 한다
import java.util.TreeSet;
public class Ex07TreeSet {
public static void main(String[] args) {
TreeSet set = new TreeSet();
set.add(new Ball(4));
set.add(new Ball(1));
set.add(new Ball(3));
System.out.println(set);
}
}
Map
key값은 중복이 불가능하지만, value 값는 중복이 가능하다
import java.util.HashMap;
import java.util.Map;
public class Ex08Map {
public static void main(String[] args) {
Map map = new HashMap();
map.put("admin","1");
map.put("user","1");
if(!map.containsKey("member"))
map.put("member","1");
System.out.println(map);
}
}
기존 key 값이 있는 경우,
key 값이 중복될 경우에는 마지막에 들어온 값이 덮어 써짐
if(!map.containsKey("member"))
map.put("member","1");
map.put("member","3");
Map map = new HashMap();
//1) key 와 value 를 동시에 접근
Iterator it = map.entrySet().iterator();
while (it.hasNext()){
Map.Entry entry = (Map.Entry)it.next();
System.out.printf("key : %s, value : %s \n" ,entry.getKey(), entry.getValue());
}
//2) key 로 접근 할때,
it = map.keySet().iterator();
while(it.hasNext()){
String key = (String) it.next();
String value = (String) map.get(key);
System.out.printf("k : %s , v: %s \n",key, value);
}
//3) value로 접근 할 때,
it = map.values().iterator();
while(it.hasNext()){
String value = (String)it.next();
System.out.println(value);
}
Map 데이터 지우기
"admin" 이라는 키를 가진 데이터를 삭제
map.remove("admin");
HashMap / TreeMap
package p07_Collection;
import p05_Inherit.common.Utils;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class Ex09MapApplicate {
private static Map phoneBook = new HashMap();
public static void main(String[] args) {
addPhone("친구", "김수한", "010-1111-1110");
addPhone("친구", "김수둘", "010-1111-1111");
addPhone("친구", "김수셋", "010-1111-1112");
addPhone("친구", "김수넷", "010-1111-1113");
addPhone("마트", "010-1111-1114");
printBook(phoneBook);
}
private static void addPhone(String group, String name, String tel) {
if(!phoneBook.containsKey(group)){
phoneBook.put(group,new HashMap<>());
}
HashMap book = (HashMap) phoneBook.get(group);
book.put(name, tel);
}
private static void addPhone(String name, String tel) {
addPhone("기타", name, tel);
}
private static void printBook(Map map) {
System.out.println(map);
Iterator it = phoneBook.keySet().iterator();
while (it.hasNext()){
String group = (String)it.next();
HashMap book = (HashMap) phoneBook.get(group);
System.out.printf("[ %s ] %d 개\n" , group, book.size());
Iterator subIt = book.entrySet().iterator();
while (subIt.hasNext()){
Map.Entry entry = (Map.Entry)subIt.next();
//Utils.typeOf(entry);
System.out.printf("[ %s ] %s \n",entry.getKey(), entry.getValue());
}
}
}
}
'PROGRAMING📚 > Java📑' 카테고리의 다른 글
Java::활용 - Stream (0) | 2024.07.05 |
---|---|
Java::Thread (0) | 2024.07.05 |
Java:: 입출력 Stream I/O (0) | 2024.06.27 |
Java :: 활용 -String (0) | 2024.06.25 |
Java::확장-extends(상속) (0) | 2024.06.25 |
댓글