'Computer/Basic Java'에 해당되는 글 5건

  1. 2018.07.30 Java에서 홈 디렉토리 구하기
  2. 2018.07.30 [Java] Date를 SimpleDateFormat으로 입맛에 맞는 시간 정보만 출력하기
  3. 2018.07.30 [Java] 가변 인자 - 갯수에 상관없이, 갯수가 정해지지 않은 인자 받기
  4. 2018.07.30 Java 8 업데이트된 내용 정리 - 람다식*
  5. 2018.07.29 [Java] 오른쪽 정렬(Right Alignment)

Java에서 홈 디렉토리 구하기

|
System.getProperty("user.home");

이처럼 사용하게 되면 OS에 상관없이 home디렉토리를 구하게 된다.
하지만 Spring 프레임워크에서 서버로의 업로드는 문제가 없지만 저장한 사진을 웹 사이트에 보여주기 위해선 HTML 태그에 src등의 속성에 대입하게 되는데 'C:\...' 혹은 '/home/...' 등의 경로가 대입이 되므로 주소명으로 다루기 위해 Project안의 WebContent폴더에 저장하게 된다.

이를테면, src='profile/xxx.jpg'라고 넣고 싶다면

String dir = req.getServletContext().getRealPath("profile"); // 폴더가 없을 경우 생성 if (!dir.exists()) { dir.mkdirs(); }

라고 해주면 profile이란 폴더가 없을 경우 폴더가 생성이 되며, 프로젝트 폴더 내부의 하위 폴더인 WebContent에 저장이 된다.
주소/Project명/profile/xxx.jpg 로 접근을 하게 되면 해당 사진을 볼 수 있게 된다.

만약 profile폴더와 사진파일 중간에 폴더를 만들고 싶다면 다음과 같이 하면 된다.
이를테면, src='profile/멤버번호/xxx.jpg'라고 넣고 싶다면

String uploadPath = req.getServletContext().getRealPath("profile"); // 디비값에 저장된 멤버의 순서(member_num)으로 하위 폴더를 만들어 구분하고 싶다면 File dir = new File(uploadPath + "/" + member.getMember_num()); // 폴더가 없을 경우 생성 if (!dir.exists()) { dir.mkdirs(); }


이렇게 되면 멤버 마다 다른 번호를 가지고 있다고 가정을 하면 매 계정마다 자기만의 폴더를 갖게 된다.


And

[Java] Date를 SimpleDateFormat으로 입맛에 맞는 시간 정보만 출력하기

|

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String date = sdf.format(articleItem.getDate()); // getDate()는 Date객체를 리턴한다. dateTV.setText(date);

And

[Java] 가변 인자 - 갯수에 상관없이, 갯수가 정해지지 않은 인자 받기

|

가변 인자는 영어로 Variable Argument라고 한다. 그러므로 클래스 이름을 VariableArgument라고 하자.

public class Solution { public static void main(String[] args) { compare(1, 2, 3, 4); compare(2, 5, 7); compare(990, 500, 240, 1000, 300, 200); } static void compare(int... args) { int max = 0; int min = 999999; for(int i : args){ if(max < i) max = i; if(min > i) min = i; } System.out.println("최대값: " + max); System.out.println("최소값: " + min); } } /** * 결과 * 최대값: 4 * 최소값: 1 * 최대값: 7 * 최소값: 2 * 최대값: 1000 * 최소값: 200 */
And

Java 8 업데이트된 내용 정리 - 람다식*

|

Functional Interfaces

Java 8에서는 두 가지 패키지가 포함되었다.

java.util.function
java.util.stream

이것으로 인해 함수 인터페이스(Functional Interfaces, 함수적 프로그래밍)를 사용할 수 있게 되었다.

Functional Interface는
- An interface that contains at most one abstract function
- Represents abstract concepts such as functions, actions, or predicates

즉, 추상 함수가 최대 하나를 포함한 인터페이스이며, 함수, 동작과 predicate 등의 추상 개념을 표현한다.

Functional Interface의 종류는 다음과 같다.

Predicate Interface
It takes one argument, returns a Boolean
Predicate는 하나의 인수를 갖으며 false나 true를 리턴한다

Consumer Interface
It accepts single argument with no return value
하나의 인수를 갖으며 리턴 값이 없다(void)

Function Interface
It accepts one argument and produces a result
하나의 인수로 결과를 도출한다.

Supplier Interface
결과에 대한 supplier들을 나타낸다. (인수는 없지만, 결과는 있다.)

UnaryOperator Interface
인수 하나, 리턴 값 하나.

BinaryOperator Interface
인수 두 개, 리턴 값 하나.

* Function Interface와 Operator Interface(UnaryOperator Interface)는 매개 값 하나, 리턴 값 하나로 같다.
서로 다른 점이 무엇일까? 주로 Operator는 이름이 말해 주듯이 연산 결과를 리턴한다. Function Interface는 일반적인 함수처럼 무엇을 넣으면 결과가 나오는 형식이다. 다만, 매개 변수는 하나다. 주로 타입 변환에 많이 사용된다고 한다.
* Consumer은 매개 값 하나, Supplier는 리턴 값 하나만 갖고 있다. 반대로 말하자면, Consumer는 리턴 값이 없고 Supplier는 매개 값이 없다.

실습

Predicate<String> stringLen = (s) -> s.length() < 10; System.out.println(stringLen.test("Apples") + " - Apples is less than 10"); // 결과: true - Apples is less than 10 || false - Apples is less tan 10 Consumer<String> consumerStr = (s) -> System.out.println(s.toLowerCase()); consumerStr.accept("ABCDefghijklmnopQRSTuvWxyZ"); // 결과: abcdefghijklmnopqrstuvwxyz Function<Integer, String> converter = (num) -> Integer.toString(num); System.out.println("length of 26: " + converter.apply(26).length()); // 결과: length of 26: 2 Supplier<String> s = () -> "Java is fun"; System.out.println(s.get()); // 결과: Java is fun BinaryOperator<Integer> add = (a, b) -> a + b; System.out.println("add 10 + 25: " + add.apply(10, 25)); // 결과: add 10 + 25: 35 UnaryOperator<String> str = (msg) -> msg.toUpperCase(); System.out.println(str.apply("This is my message in upper case")); // 결과: THIS IS MY MESSAGE IN UPPER CASE

* 람다식은 대입이 될 변수의 타입에 맞게 알아서 인식을 하게 되므로 파라미터의 형을 정하지 않고 변수명만 파라미터로 지정하면 알아서 된다.
* 매개 변수가 하나라면 괄호를 생략할 수 있다. e.g. event -> { ... }
* 하지만 매개 변수가 하나도 없으면 괄호를 해줘야 한다. e.g. () -> { ... }

Q. Funtional Interface의 종류는?

Predicate Interface
Consumer Interface
Function Interface
Supplier Interface
UnaryOperator Interface
BinaryOperator Interface

Q. 인수를 갖는 Functional Interface는?

Predicate Interface
Consumer Interface
Function Interface
UnaryOperator Interface
BinaryOperator Interface
*Supplier Interface를 제외한 모든 Interface는 인수를 갖는다. 단, BinaryOperator Interface는 인수를 두 개 갖는다.

Q. 인수를 갖지 않는 Functional Interface는?

Supplier Interface.

Q. 리턴 값이 없는 Functional Interface는?

Consumer Interface

Q. 리턴 값이 있는 Functional Interface는?

Predicate Interface
Function Interface
Supplier Interface
UnaryOperator Interface
BinaryOperator Interface
* Consumer Interface를 제외한 모든 Functional Interfaces.
* Supplier Interface는 인수가 없지만 리턴 값은 있다.

Q. boolean을 리턴하는 Functional Interface는?

Predicate Interface

매개 변수가 없으면 (), 매개 변수가 하나라면 괄호를 생략할 수 있다.
또한, { ... } 에  return문만 있을 경우 return 키워드 없이 사용한다.
e.g. (a, b) -> a + b;

* 여기서 매개 변수란

new Interface(매개 변수 자리){ // TODO }

를 의미한다. 즉, 생성자의 매개 변수를 의미한다.

자세하게는 종류가 엄청 많다. 그냥 살펴보기나 해보자.

Consumer Functional Interface
왜 Consumer라고 불릴까? 값을 accept만 하고 리턴 값없이 소비하기 때문이다.

인터페이스명
추상 메소드
Consumer<T>
void accept(T t)
객체 T를 받아 소비
BiConsumer<T, U>
void accept(T t, U u)
객체 T와 U를 받아 소비
DoubleConsumer
void accept(double value)
double 값을 받아 소비
IntConsumer
void accept(int value)
int 값을 받아 소비
LongConsumer
void accept(long value)
long 값을 받아 소비
ObjDoubleConsumer<T>
void accept(T t, double value)
객체 T와 double 값을 받아 소비
ObjIntConsumer<T>
void accept(T t, int value)
객체 T와 int 값을 받아 소비
ObjLongConsumer<T>
void accept(T t, long value)
객체 T와 long 값을 받아 소비

* Consumer Functional Interface들의 이름은 매개 변수 타입과 갯수를 의미한다.

Consumer<String> consumer = t -> { t를 소비하는 실행문; }; BiConsumer<String, String> consumer = (t, u) -> { t와 u를 소비하는 실행문; }; DoubleConsumer consumer = d -> { d를 소비하는 실행문; }; ObjIntConsumer<String> consumer = (t, i) -> { t와 i를 소비하는 실행문; };
public class ConsumerExample{ public static void main(String[] args){ Consumer<String> consumer = t -> System.out.println(t + "8"); consumer.accpet("Java"); BiConsumer<String, String> bigConsumer = (t, u) -> System.out.println(t + u); bigConsumer.accept("Java", "8"); DoubleConsumer doubleConsumer = d -> System.out.println("Java" + d); doubleConsumer.accept(8.0); ObjIntConsumer<String> objIntConsumer = (t, i) -> System.out.println(t + i); objIntConsumer.accept("Java", 8); } } /* * 결과: * Java8 * Java8 * Java8.0 * Java8 */

Supplier Functional Interface
이건 왜 또 supplier라고 불릴까? 
그것은 바로 받아 들이는 것(매개 변수) 없이 공급(리턴)을 하기 때문이다.

인터페이스명
추상 메소드
Supplier<T>
T get()
T 객체를 리턴
BooleanSupplier
boolean getAsBoolean()
boolean 값을 리턴
DoubleSupplier
double getAsDouble()
double 값을 리턴
IntSupplier
int getAsInt()
int 값을 리턴
LongSupplier
long getAsLong()
long 값을 리턴

* Supplier Functional Interface들의 이름은 리턴 값의 타입을 의미한다.

Supplier<String> supplier = () -> { ...; return "문자열"; }; IntSupplier supplier = () -> { ...; return int값; };
public class SupplierExample { public static void main(String[] args){ IntSupplier intSupplier = () -> { int num = (int) (Math.random() * 6) + 1; return num; }; System.out.println("눈의 수: " + num); } } /* * 결과: * 눈의 수: 3 */

다른 Functional Interface들도 비슷한 레파토리이기 때문에 간단하게 설명하고 넘어간다.
Function Functional Interface
매개 값과 리턴 값이 있는 applyXXX() 메소드를 갖고 있다. 매개 값을 리턴 값의 타입으로 변환하는 역할을 한다.(타입 변환, 매핑)


Operator Functional Interface
Operator Functional Interface는 Function Functional Interface와 동일하게 매개 값과 리턴 값이 있는 applyXXX() 메소드를 갖고 있다. Operator Functional Interface는 타입 변환의 역할보다 연산 후에 결과를 리턴하는 역할을 한다. (매개 값과 리턴 값은 동일 타입)

그래서 이름이 Operator(연산자) 인 것이다.

Predicate Functional Interface
Predicate Functional Interface는 매개 값과 리턴 값(boolean)이 있는 testXXX() 메소드를 갖고 있다.
매개 값을 받아서 처리 결과를 true나 false로 리턴하는 역할을 한다.


andThen(), compose()
이 두 메소드는 디폴트 및 정적메소드이다.

Consumer, Function, Operator Functional Interface는 andThen()을 가지고 있고 compose()는 가지고 있지 않은 인터페이스도 있다.

andThen()과 compose() 메소드는 순차적으로 실행을 할 때 사용되며,

두 메소드의 차이점은 어떤 것부터 처리하느냐이다.

InterfaceAB = InterfaceA.andThen(InterfaceB); result = InterfaceAB.method(); // InterfaceA부터 처리하고 그 결과를 InterfaceB의 매개 값으로 제공한다. 그 결과를 result으로 리턴한다. InterfaceAB = InterfaceA.compose(InterfaceB); result = InterfaceAB.method(); // InterfaceB부터 처리하고 그 결과를 InterfaceA의 매개 값으로 제공한다. 그 결과를 result으로 리턴한다.

* Consumer, Function, Operator Functional Interface에 대해서만 살펴 보았다. 그렇다면 Supplier와 Predicate는 어떤가?

and(), or(), negate() 디폴드 메소드와 isEqual() 정적 메소드
Predicate Functional Interface는 and(), or(), negate() 메소드를 가지고 있다. ( &&, ||, ! 과 같은 역할 )

모든 Predicate Functional Interface는 이 세 메소드를 가지고 있다.

predicateAB = predicateA.and(predicateB); result = predicateAB.test(9); // prediateA와 predicateB의 결과가 true면 true. 하나라도 false면 false가 나온다.

Predicate Functional Interface는 isEqual()인 정적 메소드도 있다.  null과 not null로 만 구분을 한다.

둘다 null이면 true, 하나라도 not null이면 false... 추가적으로 둘다 false면 sourceObject.equals(targetObject)의 리턴 값을 보여준다. 왜냐? 둘 다 null이 아니니까, 두 Object를 비교해서 이 두 Object가 같은지 아닌지 보여주기 위함이다.
* Consumer, Function, Operator 그리고 Predicate Functional Interface까지 살펴보았다.

minBy, maxBy() 정적 메소드
Operator Functional Interface는 Consumer, Function 과 다르게 이 두 정적 메소드를 갖고 있다.
모든 Operator Functional Interface가 아니라 BinaryOperator만 갖고 있다.

// Comparator 인터페이스의 생김새 @FunctionalInterface public interface Comparator<T>{ public int compare(T o1, T o2); } // 람다식으로 구현 (o1, o2) -> { ...; return int값; }; // -1( o1 < o2 ), 0( o1 == o2 ), 1 ( o1 > o2 ) 리턴

Method Reference ( 메서드 참조 )

::
이건 c++에서 namespace를 지정할 때 쓰이는 문법으로 알고 있다. 이게 Java 8에서 등장하게 되었다.
이게 뭐하는 놈일까?

다음과 같이 메서드를 참조하는 것이다.

클래스 :: 메소드
혹은
참조변수 :: 메소드

이를 테면,

Integer :: toString; Math :: max; obj :: instanceMethod;

이다.

이미 매개 변수의 갯수와 타입이 메소드에 정해져 있으므로 

(x, y) -> Math.max(x, y);

이런식으로 굳이 하지 않아도 알아 먹을 수 있다.



And

[Java] 오른쪽 정렬(Right Alignment)

|
c에서는 글자수를 맞추는 게 존재하는데, Java에서도 c처럼 출력할 수 있는 함수인 printf를 사용하면 문제를 해결할 수 있다.



/**************************************************************
    Problem: 508
    User: C-an
    Language: Java
    Result: Success
    Time:191 ms
    Memory:10244 kb
****************************************************************/
 
 
import java.io.IOException;
 
public class Main {
 
    public static void main(String[] args) throws IOException {
        System.out.printf("%10s%10s%10s\n", "item", "count", "price");
        System.out.printf("%10s%10d%10d\n", "pen", 20, 100);
        System.out.printf("%10s%10d%10d\n", "note", 5, 95);
        System.out.printf("%10s%10d%10d\n", "eraser", 110, 97);
    }
}


And
prev | 1 | next