0. 출처

[ Java - 직렬화(Serialization) ] http://boxfoxs.tistory.com/314

[ Java의 직렬화(Serialize)란? ] https://nesoy.github.io/articles/2018-04/Java-Serialize



1. 배경

직렬화 방법에는 여러 형식이 존재한다.

표 형태의 다량의 데이터를 직렬화할 때는 CSV 형식, 구조적인 데이터는 XML, JSON 형식이 있다.

객체를 파일로 저장하거나 네트워크를 통해 전송하고 싶은 경우, 객체를 JSON으로 일일이 바꿔서 전송했었다. 

위와 같은 불편한 방식을 사용하지 않고 직렬화를 이용하면 객체 그 자체를 저장하거나 전송할 수 있다.



2. 직렬화

직렬화란 무언가를 일자로 늘어 놓는다는 뜻과 같이, 

JVM(Java Virtual Machine)의 메모리에 상주(힙, 스택)되어 있는 객체 데이터를 스트림에 쓰기 위해 

연속적인 데이터(byte)로 변환하는 것이다. 

객체의 내용을 byte 단위로 변환하여 파일이나 네트워크를 통해 송수신을 가능하게 하고, 외부의 자바 시스템에서도 사용할 수 있게 한다.


객체에는 메소드가 포함되지 않는다. 하나의 클래스에는 여러 객체가 있고, 각각의 객체마다 다른 멤버변수들을 가지고 있다.  

메소드의 경우 모두가 공통적이기 때문에 객체를 저장할때는 메소드를 제외하고 순수하게 값들만 저장하게 된다.

1
2
3
4
5
6
7
class A { 
    int a; 
    int getA() { return a; } 
}
// 클래스 A 에 변수 a 와 함수 getA() 가 있다.
// 직렬화 한다는 것은 변수 a 만 바이트 코드로 나열하는 것이다.
 
cs



3. 조건

java.io.Serializable 인터페이스를 implement한다.

복잡한 데이터 구조의 클래스의 객체라도 Serializable 인터페이스를 구현하면 큰 작업 없이 바로 직렬화, 역직렬화가 가능하다.

Serializable 인터페이스는 구현해야 할 메소드가 없기 때문에 implements 선언만 해주면 된다. 

Serializable 인터페이스를 사용하는 이유는 해당 객체에게 직렬화가 제공되어야 함을 JVM에게 알려주어야 하기 때문이다.



4. 사용방법

java.io.ObjectOutputStream를 사용하여 직렬화를 진행한다.

Java에서는 직렬화를 자동으로 수행해 주는 ObjectInputStream, ObjectOutputStream을 제공한다.






'Java' 카테고리의 다른 글

객체지향 설계  (0) 2018.11.15
static과 final  (0) 2018.08.20
Overloading (오버로딩)  (0) 2018.07.28
Overriding (오버라이딩, 재정의)  (0) 2018.07.28
String, StringBuffer, StringBuilder  (0) 2018.07.17

출처: https://www.edwith.org/boostcourse-android/lecture/17094/



1. 구현 결과 화면

  



2. AndroidManifest.xml

인터넷 권한을 추가한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tistory.qlyh8.practice">
 
    <uses-permission android:name="android.permission.INTERNET" />
 
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
 
</manifest>
cs



3. activity_main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    tools:context="com.tistory.qlyh8.practice.MainActivity">
 
    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="이미지 가져오기"/>
 
    <ImageView
        android:id="@+id/image_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
 
</LinearLayout>
 
cs



4. ImageLoadTask.java

이미지가 웹서버의 어디에 위치하고 있는지에 대한 정보를 받았다면 그 파일을 다운로드할 수 있다.

객체를 생성할 때, 이미지 Url와 이 이미지를 다운로드 받은 후 화면에 보여줄 때 사용할 ImageVIew를 파라미터로 전달한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package com.tistory.qlyh8.practice.ch5;
 
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.widget.ImageView;
 
import java.net.URL;
import java.util.HashMap;
 
public class ImageLoadTask extends AsyncTask <Void, Void, Bitmap> {
 
    private String urlStr;
    private ImageView imageView;
    private HashMap<String, Bitmap> hashMap = new HashMap<>();
 
    // 어떤 url 로 요청할 지, 응답을 받은 후 어떤 이미지뷰에 설정할 지 전달받음
    public ImageLoadTask(String urlStr, ImageView imageView){
        this.urlStr = urlStr;
        this.imageView = imageView;
    }
 
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }
 
    @Override
    protected Bitmap doInBackground(Void... voids) {
        // 웹서버의 이미지 데이터를 받아 비트맵 객체로 만든다.
        Bitmap bitmap = null;
        try {
            // 메모리에 만들어진 후 해제되지 않으면 메모리에 계속 남아있는다.
            // 여러 이미지를 로딩하게 되면 메모리가 부족해지는 문제가 발생할 수 있으므로
            // 사용하지 않는 비트맵 객체는 recycle() 메소드를 이용해 즉시 해제시킨다.
            if(hashMap.containsKey(urlStr)){  // 요청 주소가 들어있다면 비트맵을 꺼냄
                Bitmap oldBitmap = hashMap.remove(urlStr);
                if(oldBitmap != null){
                    oldBitmap.recycle();    // 들어왔던 비트맵을 메모리에 제거
                    oldBitmap = null;
                }
            }
 
            URL url = new URL(urlStr);
            // 주소로 접속하여 이미지 스트림을 받고, decodeStream 을 통해 비트맵으로 바꿈
            bitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream());
 
            hashMap.put(urlStr, bitmap); // 새 비트맵을 넣음
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bitmap;
    }
 
    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
    }
 
    @Override
    protected void onPostExecute(Bitmap bitmap) {
        super.onPostExecute(bitmap);
        imageView.setImageBitmap(bitmap);   // 비트맵을 이미지뷰에 설정
        imageView.invalidate(); // 이미지를 다시 그림
    }
}
 
cs



5. MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.tistory.qlyh8.practice;
 
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
 
import com.tistory.qlyh8.practice.ch5.ImageLoadTask;
 
public class MainActivity extends AppCompatActivity {
    ImageView imageView;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        imageView = findViewById(R.id.image_view);
 
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String url = "https://movie-phinf.pstatic.net/20180620_259/1529458464756gRILM_JPEG/movie_image.jpg?type=m665_443_2";
                ImageLoadTask task = new ImageLoadTask(url, imageView);
                task.execute();
            }
        });
    }
}
cs



6. 참고

- Downloading custom sizes with Glide: https://github.com/bumptech/glide/wiki/Downloading-custom-sizes-with-Glide

- Universal Image Loader: https://github.com/nostra13/Android-Universal-Image-Loader

'Android' 카테고리의 다른 글

SQLiteOpenHelper 사용해보기  (0) 2018.08.19
SQLite database 사용해보기  (0) 2018.08.19
Volley 사용하기 - (2) JSON 요청하기  (1) 2018.07.31
Volley 사용하기 - (1)  (0) 2018.07.31
HTTP - 2. 웹으로 요청하기  (0) 2018.07.30

문제 출처: https://www.acmicpc.net/problem/2504





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;
 
public class algo7_2504_parentheses_value {
    
    public static void main(String[] args) throws NumberFormatException, IOException {
        BufferedReader reader= new BufferedReader(new InputStreamReader(System.in));
        String input = reader.readLine();
        
        int value = 0
        Stack<String> stack = new Stack<>();
        stack.push(String.valueOf(input.charAt(0)));
        
        for(int i=1 ; i<input.length() ; i++){
            String str = String.valueOf(input.charAt(i));
        
            if(str.equals("("|| str.equals("[")){    // 여는 괄호일 때 스택에 넣음
                stack.push(str);
            }
            else if(str.equals(")")){    // 닫는 괄호가 ')' 일때
                if(stack.peek().equals("(")){ // 중첩된 괄호가 아니라면 스택에 '2'를 넣는다.
                    stack.pop();
                    stack.push("2");
                }
                else{
                    int tmp = 0;
                    while (!stack.isEmpty()) { // 여는 괄호가 나올 때까지 더하고, 여는 괄호가 나오면 *2
                        String pop = stack.pop();
                        if(pop.equals(")"|| pop.equals("["|| pop.equals("]")){
                            System.out.println(0);
                            return;
                        }
                        if(pop.equals("(")){
                            stack.push(String.valueOf(tmp*2));
                            break;
                        }
                        tmp += Integer.parseInt(pop);
                    }
                    if(stack.isEmpty()){
                        System.out.println(0);
                        return;
                    }
                }
            }
            else if(str.equals("]")){    // 닫는 괄호가 ']' 일때
                if(stack.peek().equals("[")){ // 중첩된 괄호가 아니라면 스택에 '3'를 넣는다.
                    stack.pop();
                    stack.push("3");
                }
                else{
                    int tmp = 0;
                    while (!stack.isEmpty()) {    // 여는 괄호가 나올 때까지 더하고, 여는 괄호가 나오면 *3
                        String pop = stack.pop();
                        if(pop.equals("("|| pop.equals(")"|| pop.equals("]")){
                            System.out.println(0);
                            return;
                        }    
                        if(pop.equals("[")){
                            stack.push(String.valueOf(tmp*3));
                            break;
                        }
                        tmp += Integer.parseInt(pop);
                    }
                    if(stack.isEmpty()){    // 괄호 짝이 맞지 않음
                        System.out.println(0);
                        return;
                    }
                }
            }
            else {    // 괄호가 아닌 값이 들어옴
                System.out.println(0);
                return;
            }
        }
        
        while(!stack.isEmpty()){    // 스택의 있는 값을 모두 더한다.
            String str = stack.pop();
            if(str.equals("("|| str.equals(")"|| str.equals("["|| str.equals("]")){
                System.out.println(0);
                return;
            }
            value += Integer.parseInt(str);
        }
        System.out.println(value);    // 결과 출력
    }
}
 
cs




'Algorithm' 카테고리의 다른 글

백준 1992번: 쿼드트리  (0) 2018.08.08
Divide and Conquer (분할정복법)  (0) 2018.08.07
백준 1874번: 스택 수열  (0) 2018.07.23
백준 10799번: 쇠막대기  (0) 2018.07.20
백준 9012번: 괄호  (0) 2018.07.18

+ Recent posts