[자바복습 Day10] Collection, equals와 HashCode, 자바에서는 다중 상속은 불가, 다중구현은 가능, 함수형 인터페이스, Comparator, 람다식,
Collection의 List, Set, Map 모두 인터페이스이다.
ArrayList
Set set = new HashSet();
Hash의 장담점
: 데이터를 찾는 속도가 매우 빠르지만 데이터를 쌓아두기에는 좋지 않다.
: 검색이 빈번하게 일어나는 작업이라면 hash를 이용하면 좋다.
: Collision이 자주 발생하는 것이 단점, Collision 주소가 같은 값이 안나오게 하기위해서는 메모리가 커야 한다.
Map
: 데이터를 집어 넣을 때, Key와 Value 쌍으로 넣는다.
: Key는 중복되면 안된다.
: HashTable, HashMap
: 데이터 넣기 put, 빼기 get, 삭제 remove
: 파이썬에서는 딕셔너리와 유사하다.
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "홍길동");
map.put(2, "손오공");
map.put(3, "저팔계");
map.put(4, "사오정");
System.out.println(map.containsKey(4));
System.out.println(map.containsKey(5));
System.out.println(map.containsValue("손오공"));
System.out.println(map.containsValue("임꺽정"));
//순회
Iterator<Integer> iter = map.keySet().iterator();
while(iter.hasNext()) {
System.out.println("Key: " + iter.next());
}
Iterator<String> val = map.values().iterator();
while(val.hasNext()) {
System.out.println("Value: " + val.next());
}
System.out.println(map.get(1));
System.out.println(map.size());
System.out.println(map.isEmpty());
map.clear();
System.out.println(map);
출력값
true
false
true
Key: 1
Key: 2
Key: 3
Key: 4
Value: 홍길동
Value: 손오공
Value: 저팔계
Value: 임꺽정
홍길동
4
false
{}
Thread 쓰레드
: 동시에 2개 이상의 프로그램을 운영하려고 할 때 Thread를 사용함. (카카오톡 쌍방향 메신저를 생각하면 됨)
: 메모리 공간은 하나인데 2개의 프로그램이 들어와 사용함, 메모리 공간에 들어온 동안에만 순서를 지킴!
▶StringBuffer(Thread Safe, 안정), StringBuilder(Thread non Safe, 불안정)
: 둘의 차이는 동기화가 되는지 아닌지의 차이이다. StringBuffer는 안정, StringBuilder는 불안정!
: StringBuilder는 스레드에 안전여부에 전혀 관계 없는 프로그램을 개발할 때 사용하면 좋음
Thread Safe인 아이들을 찾아서 사용해야 한다.
그렇지 않은 경우 메모리 공간에 작업에 문제가 발생할 수 있음
Thread non Safe가 단점만 있는 것은 아님 Thread Safe는 락이 걸린 상황이기 때문에 기다려야함
https://aomee0880.tistory.com/150
StringBuilder쓰는이유 StringBuffer 에서 쓰레드의 동기화만 뺀 기능
StringBuilder는 문자열의 저장 및 변경을 위한 메모리 공간을 지닌 클래스이다. 문자열 데이터의 추가를 위한 append와 중간에 삽입을 위한 insert 메소드를 제공한다. append는 문자열을 순서대로 저
aomee0880.tistory.com
[과제]
Day09에 했던 내용을 Map이 되도록!바꿔보기?
내용물이 같은지 확인하는 <equals()>
기본생성자, setter, getter, toString, equals를 만들어야 함!
값이 같으면 같은건데 new때문에 다르다고 나옴.
어떻게 해결할까?
map.put("손오공", new Friend("손오공", "010-2222-3333"));
//false가 나오는 이유는 new가 있기 때문에 새롭게 만들어버림!
System.out.println(map.containsValue(new Friend("손오공", "010-2222-3333")));
출력값
false
아래와 같은 메소드를 사용한다.
주소값만 같으면 안되고 안의 내용, 값이 같아야 한다.
// equals() ==>
//현재 타입으로 전환하는 하향캐스팅을 반드시 해줘야 한다.
//하는 이유는 Object obj가 getName()을 사용할 수 없기 때문에
@Override
public boolean equals(Object obj) {
Friend temp = (Friend) obj;
String yourname = temp.getName();
String yourphone = temp.getPhone();
//내용들이 모두 같아야 같은 것이다.
if(name.equals(yourname) && phone.equals(yourphone))
return true;
return false;
}
주소값만 다르고 내용이 같다면 메모리가 낭비되지 않게 하기 위해 그것을 위해 HashCode를 사용한다.
hashCode()와 equals(Object obj)이 없을 경우에는 같은 내용물임에도 인식하지 못하기 때문에 사용한다.
@Override
//주소를 같이 써서 동일한 데이터를 쓰겠다! 이것임!
public int hashCode() {
return Objects.hash(name, phone);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Friend other = (Friend) obj;
return Objects.equals(name, other.name) && Objects.equals(phone, other.phone);
}
자바
상속 : 다중상속 불가, C++(C + OOP), 다중구현은 가능
▶함수형 인터페이스
: 본체를 가진 메소드가 존재 가능하다.
: 시그니처만 있는 메소드는 1개만 허용!
: 람다식, 람다객체를 위해서 만든 문법
@FunctionalInterface
interface MyInter1{
public void myMethod();
//함수형 인퍼페이스
public default void yourMethod() {
System.out.println("Your Method");
}
}
자바
: 객체지향 언어, 메소드가 있다. + 함수형(람다식)
파이썬, 자바스크립트
: 객체지향 언어 + 함수형 언어
자바스크립트
: 데이터 타입이 없다.
: 함수도 데이터, 함수를 전달인자로 넘기기도(함수를 데이터로 다루는 언어를 1급언어, First Class라고 한다.)
//정의
@FunctionalInterface
interface Something{
public int max(int a, int b);
}
public class FuncInterface2 {
public static void main(String[] args) {
//구현
Something some = new Something() {
@Override
public int max(int a, int b) {
return (a >= b) ? a : b;
}
};
//사용 ==> 람다 객체를 이용하면 사용을 조금 더 쉽게 사용할 수 있다.
int result = some.max(10, 5);
System.out.println("결과: " + result);
}
}
출력값
결과: 10
FunctionalInterface는 람다를 위해 출현한 제품이다,
<연습문제: 인터페이스 java.util.Comparator를 람다식으로 정의해서 둘 중 큰 데이터가 리턴되도록 만들기 >
//일반
Comparator<Integer> comp1 = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return (o1 >= o2) ? o1 : o2;
}
};
//람다식
Comparator<Integer> comp2 =(o1, o2) -> (o1 >= o2) ? o1:o2;
int big2 = comp2.compare(5, 7);
System.out.println(big2);
Collections.sort(리스트, 람다식);
List<Integer> list = Arrays.asList(6, 3, 5, 1, 8, 9, 10);
Collections.sort(list,(o1, o2) -> (o1 >= o2) ? 1 : -1);
System.out.println(list);
출력값
[1, 3, 5, 6, 8, 9, 10]
<연습문제>
: String의 CompareTo라는 메소드를 람다식 안에 사용해서 문자열이 저장된 리스트를 정렬하는 코드를 완성하라.
List<String> list = Arrays.asList("홍길동", "박원자", "스파이더맨", "킹스맨");
System.out.println(list);
Collections.sort(list, (o1, o2) -> o1.compareTo(o2));
System.out.println(list);
출력값
[홍길동, 박원자, 스파이더맨, 킹스맨]
[박원자, 스파이더맨, 킹스맨, 홍길동]
https://docs.oracle.com/javase/8/docs/api/
Java Platform SE 8
docs.oracle.com
public class StudentSortTest {
public static void main(String[] args) {
List<Student> list = Arrays.asList(
new Student("1", "홍길동", 89),
new Student("2", "손오공", 45),
new Student("3", "박진영", 12),
new Student("4", "임재범", 100),
new Student("5", "전우치", 98)
);
Collections.sort(list,(d1, d2) -> d2.compareTo(d1));
//(System.out::println)는 static메소드일 경우
list.forEach(System.out::println);
//==>완전이 같음
for(Student s : list)
System.out.println(s);
출력문
4, 임재범,100
5, 전우치,98
1, 홍길동,89
2, 손오공,45
3, 박진영,12
*consumer return타입이 없는 것!