Wrapper(포장) 클래스 : 기본 데이터 타입(primitive data type)을 객체로 다룰 수 있도록 만들어진 클래스
wrapper 클래스를 사용하면 자동으로 박싱, 언박싱이 이루어짐
기본 데이터 타입: byte, short, int, long, float, double, char, boolean
Wrapper클래스: Byte, Short, Integer, Long, Float, Double, Character, Boolean
Boxing: 기본 데이터 타입을 해당하는 wrapper 클래스 객체로 변환하는 것
ex.
int i=10;
integer intObj = integer.valueOf(i);
UnBoxing: wrapper클래스 객체를 해당하는 기본 데이터 타입으로 변환하는 것
ex.
integer intObj = new Integer(10);
int i = intObj.intValue();
Auto-boxing: 기본 데이터 타입의 값을 해당하는 wrapper 클래스 객체로 자동 변환하는 것
ex.
int i=10;
integer intObj = i;
Auto-unboxing: wrapper 클래스 객체를 해당하는 기본 데이터 타입으로 자동 변환
ex.
integer intObj = new integer(10);
int i = intObj;
package fc.java.course2.part1;
public class WrapperTest {
public static void main(String[] args) {
int a=10;
//Integer aa = new Integer(10);
Integer aa=10; //Auto-boxing
System.out.println(aa.intValue()); //Auto-Unboxing
Integer bb=20; //Auto-boxing
int b=bb; //Auto-Unboxing
float f=10.5f;
//Float ff = new Float(10.5f);
Float ff=45.6f; //new Float(45.6f); Auto-boxing
System.out.println(ff.floatValue());
Float af=49.1f;
System.out.println(af.floatValue());
float aff=af; //af.floatValue() -> Auto-boxing
System.out.println(aff);
}
}
숫자와 문자열 상호 변환:
숫자형 문자열을 정수로 변환
→ Integer.parInt()메소드 :자바에서 숫자형 문자열을 정수로 변환
정수를 문자열로 변환
→ String.valueOf()메소드, “” + 정수 방법 사용
package fc.java.course2.part1;
public class IntegerStringTest {
public static void main(String[] args) {
String str1 = "123";
String str2 = "123";
System.out.println(str1+str2);
int num = Integer.parseInt(str1)+Integer.parseInt(str2);
System.out.println(num);
int su1=123;
int su2=123;
System.out.println(su1+su2);
String str=String.valueOf(su1)+String.valueOf(su2);
System.out.println(str);
String s = su1+""+su2;
System.out.println(s);
}
}
자바 컬렉션 프레임워크(Collection Framework)API
List
ArrayList
LinkedList
Set
HashSet
TreeSet
Map
HashMap
TreeMap
package fc.java.course2.part1;
import java.util.ArrayList;
public class CollectionBasic {
public static void main(String[] args) {
//ArrayList에 5개 정수 저장 출력
//ArrayList -> object[] <--X-- int
//ArrayList -> object[] <--X-- Integer(Wrapper)
//ArrayList -> object[] <--(Auto-boxing:Integer)-- int
ArrayList<Integer> list=new ArrayList<Integer>();
list.add(10);
list.add(20);
list.add(30);
list.add(40);
list.add(50);
// int<-(Auto-unboxing)--Integer
for(int data: list){
System.out.println(data);
}
}
}
ArrayList 클래스: 순서가 있고 중복 가능한 리스트 API
package fc.java.course2.part2;
import java.util.ArrayList;
public class ListExample {
public static void main(String[] args) {
ArrayList<String> list=new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("cherry");
list.add("banana");
System.out.println(list.get(0));
System.out.println(list.get(1));
System.out.println(list.get(2));
System.out.println(list.get(list.size()-1));
list.remove(0);
list.set(1,"orange");
for(String str:list){
System.out.println(str);
}
}
}
package fc.java.model2;
import java.lang.management.MonitorInfo;
public class Movie {
private String title;
private String director;
private String year;
private String country;
public Movie(){
}
public Movie(String title, String director, String year, String country) {
this.title = title;
this.director = director;
this.year = year;
this.country = country;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDirector() {
return director;
}
public void setDirector(String director) {
this.director = director;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
@Override
public String toString() {
return "Movie{" +
"title='" + title + '\'' +
", director='" + director + '\'' +
", year='" + year + '\'' +
", country='" + country + '\'' +
'}';
}
}
package fc.java.course2.part2;
import fc.java.model2.Movie;
import java.util.ArrayList;
import java.util.ArrayList;
public class MovieListExample {
public static void main(String[] args) {
ArrayList<Movie> list = new ArrayList<Movie>();
list.add(new Movie("괴물", "봉준호", "2006", "한국"));
list.add(new Movie("기생충", "봉준호", "2019", "한국"));
list.add(new Movie("완벽한 타인", "이재규", "2018", "한국"));
for (Movie m : list) {
System.out.println(m);
}
System.out.println("+------------------+-------+----+------+");
System.out.println("+영화제목 |감독 |개봉년도|국가|");
System.out.println("+------------------+-------+----+------+");
for (Movie m : list) {
System.out.printf("|%-16s|%-8s|%4s|%-6s|\n", m.getTitle(), m.getDirector(), m.getYear(), m.getCountry());
}
System.out.println("+------------------+-------+----+------+");
String searchTitle = "기생충";
//순차검색->이진검색(*)
for(Movie m :list){
if(m.getTitle().equals(searchTitle)){
System.out.println("제목: "+m.getTitle());
System.out.println("감독: "+m.getDirector());
System.out.println("개봉년도: "+m.getYear());
System.out.println("국가: "+m.getCountry());
break;
}
}
}
}
HashSet 클래스: 순서가 없고 중복 불가능한 Set API 클래스
package fc.java.course2.part2;
import java.util.HashSet;
import java.util.Set;
public class HashSetExample {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("Apple");
set.add("Banana");
set.add("Cherry");
set.add("Apple");
System.out.println(set.size());
for(String element : set){
System.out.println(element);
}
set.remove("Banana");
for(String element : set){
System.out.println(element);
}
boolean contains = set.contains("Cherry");
System.out.println("Set contains Cherry?" + contains);
set.clear();
boolean empty=set.isEmpty();
System.out.println("Set is empty?" + empty);
}
}
package fc.java.course2.part2;
import java.util.HashSet;
import java.util.Set;
public class UniqueNumbers {
public static void main(String[] args) {
int[] nums = {1,2,3,4,5,2,4,6,7,1,3};
Set<Integer> uniqueNums= new HashSet<>();
for(int number : nums){
uniqueNums.add(number);
}
System.out.println("Unique numbers....");
for(int number:uniqueNums){
System.out.println(number);
}
}
}
Key-Value로 데이터 관리 - MAP API
package fc.java.course2.part2;
import java.util.HashMap;
import java.util.Map;
public class MapExample {
public static void main(String[] args) {
Map<String, Integer> stdScores = new HashMap<>();
stdScores.put("Kim", 95);
stdScores.put("Lee", 95);
stdScores.put("Park", 95);
stdScores.put("Choi", 95);
System.out.println("Kim's score:" + stdScores.get("Kim"));
System.out.println("Kim's score:" + stdScores.get("Lee"));
stdScores.put("Park", 92);
System.out.println("Park's score:" + stdScores.get("Park"));
stdScores.remove("Choi");
System.out.println("Choi score removal:" + stdScores.get("Choi"));
for(Map.Entry<String, Integer> entry :stdScores.entrySet()){
System.out.println(entry.getKey()+"'s score:"+entry.getValue());
}
}
}
package fc.java.course2.part2;
import java.util.HashMap;
import java.util.Map;
public class CharacterCount {
public static void main(String[] args) {
String str = "Hello World";
Map<Character, Integer> charCountMap= new HashMap<>();
char[] strArray=str.toCharArray();
for(char c : strArray){
if(charCountMap.containsKey(c)) {
charCountMap.put(c, charCountMap.get(c) + 1);
}else{
charCountMap.put(c,1);
}
}
System.out.println("Character Counts");
for(char c : charCountMap.keySet()){
System.out.println(c+":"+charCountMap.get(c));
}
}
}
제네릭
List<String> → String타입의 요소를 가지는 리스트package fc.java.model2;
public class ObjectArr<T>{
private T[] array;
private int size;
public ObjectArr(int size){
array=(T[])new Object[size];
}
public void set(int index, T value){
array[index]=value;
size++;
}
public T get(int index){
return array[index];
}
public int size(){
return array.length;
}
}
package fc.java.course2.part2;
import fc.java.model2.Movie;
import fc.java.model2.ObjectArr;
import fc.java.model2.Movie;
public class GenericTest {
public static void main(String[] args) {
/* ObjectArr<String> array = new ObjectArr<>(5);
array.set(0,"Hello");
array.set(1,"World");
array.set(2,"Java");
array.set(3,"Generic");
for(int i = 0; i<array.size();){
System.out.println(array.get(i));
*/
ObjectArr<Movie> bList = new ObjectArr<>(5);
bList.set(0,new Movie("완벽한 타인", "이재규", "2018", "한국"));
bList.set(1,new Movie("기생충", "봉준호", "2019", "한국"));
bList.set(2,new Movie("괴물", "봉준호", "2006", "한국"));
for(int i = 0;i< bList.size();i++){
System.out.println(bList.get(i));
}
}
}
자바 제네릭 타입<>
ex. ArrayList클래스
→ 제네릭 타입 사용하여 요소 타입 지정
→ 요소 타입은 ArrayList의 인스턴스를 생성할 때 매개변수로 전달 됨.
→ ex. ArrayList<String> list = new ArrayList<String>();
→ 요소의 타입으로 String지정한 것.
→ <String>은 제네릭 타입 매개변수로 ArrayList에서 사용할 요소의 타입으로 대체 됨.
→ ArrayList는 요소의 타입을 명시적 지정 가능, 타입 안전성 보장
package fc.java.course2.part2;
import fc.java.model2.Movie;
import java.util.*;
public class ArrayListGeneric {
public static void main(String[] args) {
List<Movie> list = new ArrayList<>();
list.add(new Movie("괴물", "봉준호", "2006", "한국"));
//list.add("Hello"); // X
list.add(new Movie("기생충", "봉준호", "2019", "한국"));
System.out.println(list.get(0));
System.out.println(list.get(1));
}
}
자바 제네릭 - 멀티 타입 파라미터
package fc.java.model2;
//유연성, 재사용성, 타입의 안전성 보장
public class Pair <K,V>{
private K key;
private V value;
public Pair(K key, V value){
this.key=key;
this.value=value;
}
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
}
package fc.java.course2.part2;
import fc.java.model2.Pair;
import java.util.*;
public class PairGenericTest {
public static void main(String[] args) {
Pair<String, Integer> pair = new Pair<>("hello", 1);
System.out.println(pair.getKey());
System.out.println(pair.getValue());
//검색을 빠르게 할 수있는 자료구조(HashMap, HashTable)
Map<String, Integer> maps = new HashMap<>();
maps.put("kor", 60);
maps.put("eng", 80);
maps.put("math", 70);
System.out.println(maps.get("kor"));
System.out.println(maps.get("eng"));
System.out.println(maps.get("math"));
}
}
Pair 클래스가 K와 V라는 두 개의 제네릭 타입 파라미터를 가지고 있음.
Pair클래스의 생성자에서는 K와 V를 각각 인자로 받아들이며, 객체의 key와 value 필드에 저장
자바 제네릭 - 제한된 타입 파라미터
package fc.java.model2;
public class AverageCalculator <T extends Number>{
private T[] numbers;
public AverageCalculator(T[] numbers){
this.numbers=numbers;
}
public double calculatorAverage(){
double sum = 0.0;
for(T number:numbers) {
sum+=number.doubleValue();
}
return sum/numbers.length;
}
}
package fc.java.course2.part2;
import fc.java.model2.A;
import fc.java.model2.AverageCalculator;
public class GenericLimitTest {
public static void main(String[] args) {
Integer[] integers={1,2,3,4,5};
Double[] doubles={1.0,2.0,3.0,4.0,5.0};
AverageCalculator<Integer> integerAverageCalculator=new AverageCalculator<>(integers);
double integerAverage=integerAverageCalculator.calculatorAverage();
System.out.println(integerAverage);
AverageCalculator<Double> doubleAverageCalculator=new AverageCalculator<>(doubles);
double doubleAverage=doubleAverageCalculator.calculatorAverage();
System.out.println(doubleAverage);
}
}
함수형 인터페이스
@FunctionalInterface 어노테이션을 사용하여 표시 가능→ 이 어노테이션은 선택 사항, 컴파일러에게 해당 인터페이스가 함수형 인터페이스임을 알려줌
자바에서 함수형 인터페이스를 사용하는 이유
package fc.java.model2;
@FunctionalInterface
public interface MathOperation {
int operation(int x, int y);
}
package fc.java.course2.part2;
import fc.java.model2.MathOperation;
public class FunctionalInterfaceTest implements MathOperation {
public static void main(String[] args) {
MathOperation mo = new FunctionalInterfaceTest();
int result = mo.operation(10, 20);
System.out.println("result = " + result);
}
@Override
public int operation(int x, int y) {
return x + y;
}
}
package fc.java.model2;
public class MathOperationImpl implements MathOperation{
@Override
public int operation(int x, int y) {
return x+y;
}
}
package fc.java.course2.part2;
import fc.java.model2.MathOperation;
import fc.java.model2.MathOperationImpl;
public class FunctionInterfaceTest1 {
public static void main(String[] args) {
MathOperation mo = new MathOperationImpl();
int result = mo.operation(10, 20);
System.out.println("result = " + result);
}
}
package fc.java.course2.part2;
import fc.java.model2.MathOperation;
import fc.java.model2.MathOperationImpl;
public class FuntionInterfaceTest2 {
public static void main(String[] args) {
//MathOperation 인터페이스를 내부 익명내부클래스로 구현
MathOperation mo = new MathOperation(){
@Override
public int operation(int x, int y) {
return 0;
}
};
int result = mo.operation(10, 20);
System.out.println("result = " + result);
}
}
이미 정의된 메서드를 직접 참조하여 람다 표현식을 더욱 간결하게 만들 수 있음
메서드 참조 4가지 유형
package fc.java.model2;
@FunctionalInterface
public interface Converter <F, T>{
T convert(F from);
}
package fc.java.model2;
public class IntegerUtils {
//정적메서드, 클래스 메서드
public static int stringToInt(String s){
return Integer.parseInt(s);
}
}
package fc.java.course2.part2;
import fc.java.model2.Converter;
import fc.java.model2.IntegerUtils;
public class IntegerUtilsTest {
public static void main(String[] args) {
Converter<String, Integer> converter = IntegerUtils::stringToInt;
int result = converter.convert("123");
System.out.println("result = " + result);
}
}
package fc.java.model2;
public class StringUtils {
//인스턴스메서드
public String reverse(String s){
return new StringBuffer(s).reverse().toString();
}
}
package fc.java.course2.part2;
import fc.java.model2.Converter;
import fc.java.model2.StringUtils;
public class StringUtilsTest {
public static void main(String[] args) {
StringUtils stringUtils = new StringUtils();
//인스턴스 메서드 참조
Converter<String, String> converter=stringUtils::reverse;
String result = converter.convert("hello");
System.out.println("result = " + result);
}
}
package fc.java.course2.part2;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class SoftCompareTest {
public static void main(String[] args) {
List<String> names= Arrays.asList("홍길동","김길동","이길동");
Collections.sort(names, String::compareTo);
System.out.println(names);
for(String name: names){
System.out.println(name);
}
}
}
package fc.java.model2;
@FunctionalInterface
public interface PersonFactory {
public Person create(String name, int age);
}
package fc.java.course2.part2;
import fc.java.model2.Person;
import fc.java.model2.PersonFactory;
public class PersonFactoryTest {
public static void main(String[] args) {
/* PersonFactory personFactory = Person::new;
Person person = personFactory.create("홍길동", 40);
System.out.println(person); */
PersonFactory personFactory = new PersonFactory() {
@Override
public Person create(String name, int age) {
return new Person(name, age); }
};
Person person = personFactory.create("나길동", 23);
System.out.println(person);
}
}
자바 람다식
람다식 구조
(parameters) → {expression}
parameters: 메서드에서 사용할 매개변수
expression: 메서드의 구현체
(매개변수) → {실행문};
람다식
package fc.java.part2;
import fc.java.model2.MathOperation;
import fc.java.model2.MathOperationImpl;
public class LambdaExample {
public static void main(String[] args) {
//MathOperation add= (int x, int y) -> { return x+y; };
MathOperation add= (x, y) -> x+y; //위를 간결하게 표현
MathOperation multi= (x, y) -> x*y;
int result = add.operation(10, 20);
System.out.println("result = " + result);
int mulresult = multi.operation(10,20);
System.out.println("mulresult =" + mulresult);
}
}
아래 코드는 대문자 소문자 변환하는 람다 표현식으로 구현된 인터페이스임.
람다 표현식은 메서드 내에서 사용 가능하며 메서드의 인자로 전달할 수도 있어 유연성을 높일 수 있음
package fc.java.model2;
@FunctionalInterface
public interface StringOperation {
public String apply(String s);
}
package fc.java.part2;
import fc.java.model2.StringOperation;
public class LambdaApply {
public static void main(String[] args) {
StringOperation toUpperCase = s->s.toUpperCase();
StringOperation toLowerCase = s->s.toLowerCase();
String input = "Lambda Expression";
System.out.println(processString(input, toUpperCase));
System.out.println(processString(input, toLowerCase));
}
public static String processString(String input, StringOperation operation){
return operation.apply(input);
}
}
배열을 스트림으로 변환
→ 배열의 원소들을 스트림 형태로 변환하여 처리할 수 있게 하는 것
→ 스트림은 원본 데이터를 변경하지 않고, 필요한 데이터 처리 작업을 적용한 결과를 생성하기 때문에 인덱스를 통한 직접 접근은 제공하지 않음
스트림
package fc.java.part2;
import java.lang.reflect.Array;
import java.util.Arrays;
public class StreamAPITest {
public static void main(String[] args) {
int[] numbers={1,2,3,4,5};
/* int even =0;
for (int num : numbers){
if(num%2==0){
even+=num;
}
}
IntStream stream=Arrays.stream(numbers);
*/
int sumOfEvens = Arrays.stream(numbers)
.filter(n->n%2==0)
.sum();
System.out.println("sumOfEvens = " + sumOfEvens);
int [] evenNumbers= Arrays.stream(numbers)
.filter(n->n%2==0)
.toArray();
for(int even : evenNumbers){
System.out.println("even = " + even);
}
}
}
스트림의 두 가지 연산
→ 스트림의 원소를 변환, 필터링, 정렬 등 중간 단계에서 처리하는 연산 ex. filter(), map(), sorted(), distinct(), limit(), skip()
→ 스트림의 최종결과를 반환하는 연산 ex. forEach(), count(), collect(), reduce(), min(), max()
package fc.java.part2;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class StreamExample {
public static boolean isEven(int number){
return number%2==0;
}
public static void main(String[] args) {
List<Integer> numbers= Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Predicate<Integer> isEven=n->n%2==0;
int sumOfSquares = numbers.stream()
.filter(isEven)
.sorted()
.map(n->n*n)
.reduce(0, Integer::sum);
System.out.println("sumOfSquares = " + sumOfSquares);
}
}
package fc.java.part2;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class MapStreamExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1,2,3,4,5);
List<Integer> squaredNumbers = numbers.stream()
.map(n->n*n)
.collect(Collectors.toList());
System.out.println("squaredNumbers = "+squaredNumbers);
}
}
package fc.java.part2;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class MapStreamExample2 {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "banana", "cherry", "orange");
List<String> uppercase = words.stream()
.map(word->word.toUpperCase())
.collect(Collectors.toList());
System.out.println("uppercase = "+uppercase);
for(String str : uppercase){
System.out.println(str);
}
}
}