프로그램을 코딩하다보면 줄바꿈, 들여쓰기, 중괄호의 위치 등의 형태가 일관성이 없을 때가 있습니다.

 

하나씩 일일이 확인하기에는 머리가 아프고, 한다고 해도 한 두개씩은 꼭 놓치게 되죠.

 

이클립스는 이런 상황을 대비하여 자동줄맞춤 기능을 지원해 주고 있습니다.

 

 

 

여기 한 눈에 보아도 뒤죽박죽인 소스를 정리해 보도록 하겠습니다.

 

 

 

Ctrl  +  a  로 소스코드 전체 영역을 선택합니다.

 

 

전체 영역이 선택된 상태에서 Ctrl  +  Shift  +  f  를 입력합니다. 

이클립스에 자동줄맞춤이 한 번에 적용되어 깔끔히 정리되었습니다. 

 

 

 

또 다른 방법으로 마우스 우클릭 > Refactor > Format 을 클릭하시면

동일하게 소스가 정리 되는 것을 확인하실 수 있습니다.

 

 

'IT > Eclipse' 카테고리의 다른 글

이클립스 자동완성  (0) 2015.04.09
이클립스 메모리 설정  (0) 2015.04.08
이클립스 글자크기 변경하기  (0) 2015.03.23
이클립스 단축키  (0) 2015.03.15
이클립스 테마 적용하기  (0) 2015.03.10

Posted by maze1008
,

인터넷 익스플로러 는 한국인이 가장 많이 사용하는 브라우저 입니다.

 

크롬, 파이어폭스, 사파리 등의 사용도 늘어나고 있지만 단독으로 이용하기 보다는

 

인터넷 익스플로러와 함께 설치하여 사용되고 있습니다.

 

 

최소 하루에 한 번, 대부분은 여러번 실행하여 인터넷의 도움을 받고 있죠!

 

하지만 나도 모르는 사이 브라우저의 버전이 업데이트 되어 실행에 오류가 발생하는 경우

 

가장 먼저 익스플로러 버전 확인 을 시도해 보아야 합니다.

 

종종 업데이트 된 상태에서 문제가 발생해서 조치가 필요하기 때문입니다.

 

 

그래서 오늘은 간단하지만 유용한 인터넷 익스플로러 버전 확인 방법을 알아보도록 하겠습니다.

 

 

인터넷 익스플로러 를 실행합니다.

아주 익숙한 네이버 화면이 나타납니다.

 

 

익스플로러 버전 확인 방법은 총 2가지 입니다.

 

 

첫 번째 방법은 설정 메뉴를 사용하는 것입니다.

상단 우측에 설정(톱니바퀴 아이콘) 메뉴 클릭 > Internet Explorer 정보(A) 클릭 합니다.

 

 

 

두 번째 방법은 도움말 메뉴를 사용하는 것입니다.

상단 중앙에 도움말(물음표 아이콘) 메뉴 클릭 > Internet Explorer 정보(A) 클릭 합니다.

 

 

 

두 가지 방법으로 Internet Explorer 정보(A) 를 클릭하면

Internet Explorer 정보 다이얼로그가 나타납니다.

 

상단에 크게 Internet Explorer 10 이라는 문구가 보이시나요?

 

익스플로러 버전이 10 이라는 의미 입니다.

아래쪽으로 상세한 세부 버전 정보도 표시됩니다.

 

마지막으로 자동으로 새 버전 설치(I) 항목이 위치하고 있는데요.

체크해 놓으면 새로운 버전이 발행될 때 자동으로 업데이트가 되는 기능입니다.

버전이 업데이트 될 때 오류가 발생하는 경우가 종종 있기 때문에 체크해제 해 놓으시길 추천합니다.

 

생각보다 인터넷 익스플로러 버전 확인 간단하죠!

 

 

Posted by maze1008
,

지난 포스트에서 안드로이드 APK 파일을 만드는 방법에 대해 소개해 드렸는데요.

안드로이드 APK 파일 만들기

 

오늘은 작성된 APK 파일을 스마트기기에 설치하여 사용하는 법에 대해 알아보도록 하겠습니다.

 

 

 

스마트기기에 설치할 apk 파일입니다.

(저는 지난 포스트에서 생성한 apk 파일을 사용하겠습니다.)

 

 

 

USB 를 사용하여 PC 에 스마트기기를 연결합니다.

컴퓨터 아이콘을 더블 클릭하면 휴대용 장치 아래로 연결된 스마트기기가 나타납니다.

스마트기기를 더블클릭 합니다.

 

 

 

 

Phone 을 더블클릭합니다.

(저는 스마트폰을 연결했습니다.)

 

 

 

apk 파일을 저장할 폴더를 생성합니다.

(이름은 간단하게 APK 라고 입력했습니다.)

 

 

 

생성한 폴더 안으로 설치할 apk 파일을 복사합니다.

 

 

 

 

이제 스마트기기에서 설치를 진행해 볼까요?

 

 

 

제가 이용하는 스마트기기에는 "내 파일" 이라는 파일 관리자 앱이 설치되어 있어서

스마트기기에 저장된 폴더와 파일들을 확인해 볼 수 있습니다.

 

혹시 유사한 앱이 없으신 분들은 구글 앱스토어에서 파일 관리자를 검색한 후 설치하시기 바랍니다.

폴더와 파일의 구조를 확인할 수 있다면 저와 동일한 앱이 아니어도 괜찮습니다!

 

파일 관리자 앱을 실행해 주세요.

 

 

 

모든 파일을 터치합니다.

 

 

 

스마트기기에 폴더 구조가 보여집니다.

PC 에서 Phone 아래에 나타났던 것과 동일한 형태입니다.

 

apk 파일을 저장했던 APK 폴더를 터치합니다.

 

 

 

PC 에서 저장했던 HelloWorld.apk 파일이 나타났습니다.

HelloWorld.apk 파일을 터치합니다.

(apk 확장자를 가지고 있는 파일을 터치하게 되면 스마트기기에 설치가 자동으로 진행됩니다.)

 

 

 

스마트기기에 앱을 설치하는 일반적인 방법은 구글 앱스토어를 통한 것입니다.

그 외의 방법으로 설치되는 앱들은 출처가 명확하지 않기 때문에 설치를 권장하지 않습니다.

따라서 apk 파일을 디바이스에 설치하기 위해서는 보안과 관련된 해제 설정이 필요합니다.

 

설정 버튼을 클릭합니다.

 

 

 

설정에 보안 페이지를 자동으로 보여줍니다.

알 수 없는 출처를 체크 합니다.

(구글 앱스토리 외에 다른 방법으로도 앱을 설치할 수 있게 허용한다는 의미입니다.)

 

 

다시 한 번 확인을 묻는 부분입니다.

사실 이 부분은 체크 해제가 되어 있어야 악성 프로그램의 무단 설치를 방지할 수 있습니다.

한번만 설치 허용 체크 > 확인 버튼을 클릭합니다.

(한번만 설치 허용을 체크하면 이번 한번만 apk 설치를 허용하게 되며,

추후에 다른 apk 파일을 설치하려고 할 때 지금과 같이 확인하는 과정을 거치게 됩니다.)

 

 

마지막으로 설치를 묻는 화면입니다.

 

만약 개발한 앱이 기기에 대한 인터넷, 파일, 카메라 등의 권한을 필요로 한다면

권한에 대한 승인을 묻는 화면이 나타나게 됩니다.

 

설치를 터치합니다.

 

 

 

이제 드디어 설치가 진행됩니다.

 

 

설치가 완료되고 바로 실행 할 것인지 묻는 화면입니다.

열기를 터치합니다.

 

 

 

APK 설치가 완료되고 앱을 실행한 화면입니다.

 

드디어 안드로이드 APK 설치 과정이 모두 완료되었습니다.

 

Posted by maze1008
,

안드로이드 앱을 개발하여 스마트기기에 배포하기 위해서는 APK 파일로 만들어야 합니다.

 

안드로이드 프로젝트 만들기 - Hello World 에서

프로젝트를 만들고 실행하는 과정(Run As > Android Application) 에서도 APK 파일이 내부적으로 생성되어 스마트폰기기(또는 에뮬레이터)에 설치된다고 볼 수 있습니다.

 

이번 포스팅에서는 APK 파일을 만드는 방법에 대해 소개해 드리도록 하겠습니다.

 

 

 

이클립스를 실행하고

APK 파일로 만들고 싶은 프로젝트(HelloWorld 를 선택했습니다.)   > 마우스 우클릭 > Export...  를 클릭합니다.

 

 

 

Android 폴더 아래의 Export Android Application 을 선택하고 Next 버튼을 클릭합니다.

 

 

 

프로젝트 이름을 확인한 후 Next 버튼을 클릭합니다.

 

 

 

APK 파일은 keystore 의 저장된 key 를 사용하여 서명 후 발행되는데

처음 APK 파일을 만드는 과정이기 때문에 당연히 keystore 가 존재하지 않습니다.

 

따라서 Create new keystore 라디오 버튼을 선택하고, 아래 항목을 입력한 후 Next 버튼을 클릭합니다.

Location : keystore 파일이 생성될 위치와 파일 이름

Password / Confirm : keystore 파일에 사용될 비밀번호 (6자리 이상)

 

Location 옆에 위치한 Browse... 버튼을 클릭하여 keystore 파일이 생성될 위치를 선택한 후 반드시 파일 이름을 입력해 주시기 바랍니다.

(저는 C:\Users\user\Desktop\keystore 폴더를 선택한 후, keystore 파일 이름을 key 로 입력했습니다.)

 

 

 

다음으로는 생성된 keystore 에 저장될 새로운 key 를 만들어야 합니다.

key 의 이름, 비밀번호, 유효기간 등을 간략히 입력한 후 Next 버튼을 클릭합니다.

Alias : key 의 이름

Password / Confirm : key 의 비밀번호

Validity (years) : key 의 유효기간 (최대 60년)

First and Last Name : 이름

 

 

 

마지막으로 APK 파일이 생성될 위치를 지정한 후에 Finish 버튼을 클릭합니다.

앞에서 생성한 key 로 서명된 APK 파일을 작성됩니다.

 

 

 

HelloWorld.apk 파일이 만들어졌습니다.

 

다음 시간에는 APK 파일을 스마트기기에 설치하는 방법에 대해서 알아보도록 하겠습니다. 

 

Posted by maze1008
,

내 IP 주소 확인법

IT/ETC 2015. 4. 2. 10:00

IP 란 Internet Protocol 의 약자 입니다.

 

네트워크를 이용하는 기기(컴퓨터, 노트북, 프린터, 스마트폰 등)들에 부여되는 정보이지요.

 

하지만 인터넷은 익숙하게 사용하면서도 IP 주소 확인법은 알지 못하는 분들도 많이 계신것 같습니다.

 

 

지금부터 간단하지만 유용한 내 IP 주소 확인법에 대해 알아보도록 하겠습니다.

 

 

1. 명령 프롬프트(터미널)에서 확인하기

 

개발자(프로그래머) 분들께서 일반적으로 사용하는 방법 입니다.

 

 

 

시작 메뉴를 클릭하여 cmd 를 입력후 Enter 버튼을 누릅니다.

 

 

 

명령 프롬프트(터미널) 에서 ipconfig /all 을 입력합니다.

이더넷 어댑터 로컬 영역 연결 아래에 IPv4 주소가 바로 내 IP 주소 입니다.

(예를 들면 10.10.10.10  이렇게 표현됩니다.)

 

 

 

 

2. 제어판에서 확인하기

 

명령 프롬프트를 자주 사용해보지 않으신 분들께서는 2번째 방법을 사용하셔도 같은 결과를 얻을 수 있습니다.

(명령 프롬프트는 개발자에게 익숙한 화면이므로, 일반 사용자분들께는 낯설게 느껴지실 겁니다.)

 

 

 

시작 메뉴를 클릭하여 제어판을 선택합니다.

 

 

 

네트워크 및 인터넷 하위에 네트워크 상태 및 작업 보기를 클릭합니다.

 

 

 

로컬 영역 연결을 클릭합니다.

 

 

 

자세히(E)... 버튼을 클릭합니다.

 

 

 

명령 프롬프트에서 보여졌던 IP 주소 확인 정보가 IPv4 주소에서도 나타납니다.

(예를 들면 10.10.10.10  이렇게 표현됩니다.)

  

 

 

3. 네이버에서 확인하기

 

마지막으로 네이버를 통해서도 확인이 가능합니다.

 

 

네이버 검색창에 IP 주소 라고 입력하시면, 아주아주 간단하게 확인이 가능합니다.

(공유기를 사용하신다면 명령 프롬프트, 제어판에서 확인한 정보와 네이버에서 확인한 정보가 다를 수 있습니다.  이 때는 네이버에서 나타난 실제 IP 주소가 공유기를 거치면서 여러개의 임의 IP 로 분리되었다고 이해하시면 좋을 것 같습니다.)

 

 

* 우분투에서 내 IP 주소 확인법

(1) 터미널 > ifconfig -a | grep eth 입력 (또는 ifconfig -a) > inet addr 확인

(2) 네트워크 > 유선 > IP 주소 확인

 

Posted by maze1008
,

처음 인터넷 사이트에 가입하셨던 때를 기억하시나요?

 

오래된 기억같지만 인터넷이 보급되고 사용이 일반화된 일은 그리 멀지 않은 과거의 일입니다.

 

 

하지만 어느새 넘쳐나는 사이트와 정보를 속에서 이제는 가입한 사이트가 어디였었는지

 

아이디, 비밀번호가 무엇이었는지도 헷갈리는 시대가 되었지요.

 

사이트에 들어가서 "아이디, 비밀번호 찾기" 를 하는 일도 그만큼 많아졌습니다.

 

 

정보가 범람하는 시대에서 어찌보면 익숙한 일이지만

 

뉴스에서 개인 정보 유출 소식을 들을 때면 내가 가입한 사이트 였었나? 라는 생각에 걱정이 앞서기도 합니다.

 

그래서 오늘은 내가 가입한 사이트 조회하기 에 대해  소개해 드리고자 합니다.

 

 

 

아래 링크를 통해서 주민등록번호 클린센터(KISA) 에 방문합니다.

http://clean.kisa.or.kr/mainList.do

 

 

주민등록번호 클린센터(KISA) 에서는 주민등록번호 이용내역을 확인해서

내가 가입한 사이트 조회하기 기능을 제공하고 있습니다.

 

GO 버튼을 클릭합니다.

 

 

 

 

개인정보 수집 및 동의를 묻는 부분입니다.

3가지 항목에 동의함을 체크 > 확인 버튼을 클릭합니다.

 

 

 

본인 인증을 하는 부분입니다. (다른 사람이 제 정보를 확인하지 못하게 하는 것이죠!)

명, 주민등록번호를 입력 > 실명확인 버튼을 클릭합니다.

 

 

 

원하는 인증 방법을 선택하여 인증절차를 완료합니다.

(저는 간단하게 휴대폰을 사용했습니다.)

 

 

 

드디어 내가 가입한 사이트 조회하기 결과 확인을....?!

 

화면 상단에 "전체 0건 검색되었습니다." 라는 문구가 나타났습니다.

제가 가입한 사이트가 1개도 없어서 저렇게 표시되는 걸까요?  당연히 아닙니다!

 

주민등록번호 클린센터(KISA) 에서 실제로 제공하는 기능은 주민등록번호 이용내역을 확인하는 것입니다.

내가 가입한 사이트 조회하기 기능이 아니라는 것이죠.

 

화면 상단에 나타난 문구는 제가 2015년에 새로 가입한 사이트가 0 개 라는 의미입니다.

 

하지만 그 아래쪽에 위치한 4가지 조회 방법을 클릭해 보시면

(SCI 서울 신용평가정보, 한국신용정보주식회사, 한국신용평가정보, 코리아크레딧뷰로)

 

올해가 아닌 지난 몇 년동안의 주민등록번호 이용내역을 확인하실 수 있습니다.

 

 

 

화면의 리스트에 표시된 사이트 주소와 인증일시를 보고

"홈페이지탈퇴 요청하기" 버튼을 통해 사이트를 정리하면 꽤 유용하겠죠?

 

 

제가 오늘 소개해 드린 내가 가입한 사이트 조회하기 기능을 1년에 한 번씩이라도 꾸준히 사용하셔서

더 적극적으로 자신의 정보를 보호하는 우리가 되어 보자구요!!

 

'IT > ETC' 카테고리의 다른 글

인터넷 익스플로러 버전 확인  (0) 2015.04.06
내 IP 주소 확인법  (0) 2015.04.02
CMD (명령 프롬프트) 명령어 모음  (3) 2015.03.22
Beyond Compare - 폴더, 파일 비교하기  (0) 2015.03.21
CSV 파일 변환  (0) 2015.03.12

Posted by maze1008
,

GIT 은 프로그램을 여러명이 동시에 개발할 때 소스코드를 편리하게 관리/운영 할 수 있게 도와주는 버전관리 툴입니다.

 

SVN 과 함께 양대산맥처럼 사용되고 있으며, 개인적 경험으로는 GIT 을 더 오랜기간 사용하고 있습니다.

 

처음 이용할 때에는 개념적으로 어렵게 느껴질 수도 있지만 익숙해질수록 그 유용함에 절로 고개가 끄덕여질 만큼 고마운 개발지원 도구 입니다.

 

 

오늘은 GIT 을 사용하는 시작점으로 윈도우에서 GIT 을 설치하는 방법에 대해 소개해 드리도록 하겠습니다.

 

 

 

1. GIT 다운로드

 

아래 링크를 통해서 GIT 홈페이지를 방문하시면 무료로 다운 받을 수 있습니다.

http://www.git-scm.com/

 

 

Downloads for Windows 버튼을 클릭합니다.

 

 

 

브라우저 아래쪽으로 바로 실행 or 저장을 묻는 화면이 나타납니다.

실행을 선택합니다.  

 

 

 

 

 

2. GIT 설치

 

 

Next 버튼을 클릭하여 설치를 시작합니다.

 

 

 

GIT 에 대한 라이센스를 공지하는 부분입니다.

Next 버튼을 클릭합니다.

 

 

 

설치될 위치를 확인하고 Next 버튼을 클릭합니다.

 

 

 

Advanced context menu (git-cheetah plugin) 이 체크되어 있는지 확인하고, Next 버튼을 클릭합니다.

(이 옵션은 마우스 우클릭시 나타나는 컨텍스트 메뉴에 GIT 을 추가할 것인지 묻는 부분입니다.)

 

 

 

GIT 의 shortcut 생성 위치를 묻는 부분으로 Next 버튼을 클릭합니다.

 

 

 

GIT 을 사용하기 위한 환경을 설정하는 부분입니다.

 

(1) Use Git from Git Bash only

해당 프로그램에서 제공해주는 Git Bash 에서만 Git 을 사용할 수 있도록 설치합니다.

 

(2) Use Git from the Windows Command Prompt

윈도우에 명령 프롬프트에서도 Git 을 사용할 수 있도록 설치합니다.

 

(3) Use Git and optional Unix tools from the Windows Command Prompt

명령 프롬프트에서 몇가지 유닉스 도구와 Git 을 사용할 수 있도록 설치합니다.

(윈도우와 유닉스가 같은 명령을 가지고 있다면(예를 들어 find, sort) 해당 명령어의 경로를 덮어써서 기존과 다르게 동작할 수도 있으므로 주의해야 합니다.)

 

2번째 옵션인 Use Git from the Windows Command Prompt 를 체크하고

Next 버튼을 클릭합니다.

 

 

 

행 변환과 관련된 내용으로 첫번째 옵션인 Checkout Windows-style, commit Unix-style line endings 를 체크하고 Next 버튼을 클릭합니다.

 

 

 

옵션 설정이 모두 끝나고 설치가 진행중입니다.

 

 

 

 

드디어 설치가 완료되었습니다.

Finish 버튼을 클릭합니다.

 

 

 

 

3. GIT 실행

 

 

 

바탕화면에서 마우스 우클릭하면 설치할때 설정한 옵션에 따라 GIT 과 관련된 3가지 메뉴가 추가되어 있는 걸 확인할 수 있습니다.

 

GIT 은 2가지 옵션 형태로 사용할 수 있는데요.

 

 

 

 

Git Gui 항목을 클릭하면 다음과 같은 다이얼로그가 나타나며

UI 화면을 통해서 기능들을 사용할 수 있는 그래픽 인터페이스가 제공됩니다.

 

 

 

 

 

Git Bash 항목을 클릭하면 명령어를 입력할 수 있는 창(커맨드라인 제공)이 나타나는 것을 확인할 수 있습니다.

Git Bash 를 이용하여 작업한다면 이후에 유닉스 등에서도 동일한 방법으로 사용하실 수 있기 때문에

Git Cui 보다는 이 옵션에 익숙해 지시길 추천드립니다.

 

 

 

 

GIT 설치가 정상적으로 이루어졌는지 간단하게 알아보기 위해서 version 을 확인해 보았습니다.

 

설치할 때 설정한 옵션에 따라 명령 프롬프트에서도 (Git Bash 와) 동일한 작업이 가능합니다.

 

 

'IT > GIT' 카테고리의 다른 글

이클립스에 GIT 설치하기 (EGit 플러그인)  (0) 2015.04.13

Posted by maze1008
,

자바(Java) 에 대해 공부하면서 다음과 같은 말을 많이 들어보았을 것입니다.

 

깊은 복사(deep copy) 와 얕은 복사(shallow copy)

참조 복사(call by reference) 와 값 복사(call by value)

 

값을 다른 곳에 복사하여 사용할 때, 복사가 이루어지는 방법에 따라 동작에 많은 영향을 미치게 됩니다.

지금부터 ArrayList 를 사용하여 두 가지 방법이 어떤 차이점을 가지고 있는지 알아보도록 하겠습니다.

 

 

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
import java.util.ArrayList;
 
public class CopyTest {
    static ArrayList<String> source = new ArrayList<String>();
    static ArrayList<String> destination = new ArrayList<String>();
    
    public static void initArrayList() {
        if (null != source) {
            source.clear();
            source.add("apple");
            source.add("banana");
            source.add("cherry");
        }
 
        if (null != destination) {
            destination.clear();
        }
    }
    
    public static void printArrayList() {
        System.out.println("====== source result ======");
        for (int i = 0; i < source.size(); i++) {
            System.out.println("source ["+i+"] : " +source.get(i));
        }
 
        System.out.println("====== destination result ======");
        for (int i = 0; i < destination.size(); i++) {
            System.out.println("destination ["+i+"] : " +destination.get(i));
        }
    }
 
    public static void main(String[] args) {
        initArrayList();
 
        // TODO : operation
        
        printArrayList();
    }
}
 
cs

 

 

코드를 간단히 살펴보면,  2 개의 ArrayList 가 선언되어 있고(source, destination)

main() 메소드의 // TODO : operation  위치에서 다음과 같은 2가지 동작을 수행한 후

각각의 ArrayList 가 가지고 있는 값을 모두 출력하게 됩니다. 

1. source 에 있는 내용을 destination 에 복사

2. destination 에 항목을 1개 추가

 

 

동일한 동작을 얕은 복사와 깊은 복사로 적용해 보았습니다.

1. 얕은 복사(shallow copy)      

destination = source;

destination.add("kiwi");

  

<결과>

destination 에만 추가한 kiwi 가 source 에도 추가되어 있음을 확인할 수 있습니다.

shallow copy 는 원본과 복사본 둘 중 한쪽의 수정이 양쪽에 모두 영향을 미치게 됩니다.

 

====== source result ======
source [0] : apple
source [1] : banana
source [2] : cherry
source [3] : kiwi 
====== destination result ======
destination [0] : apple
destination [1] : banana
destination [2] : cherry
destination [3] : kiwi

 

2. 깊은 복사(deep copy)      

destination.addAll(source) ; // 또는 destination =(ArrayList<String>)source.clone();

destination.add("kiwi");

  

<결과>

destination 에만 추가한 kiwi 가 source 에는 존재하지 않음을 확인할 수 있습니다.

deep copy 는 원본과 복사본 둘 중 한쪽의 수정이 다른 한쪽에 영향을 미치지 않습니다.

주석으로 표기한 방법으로도 같은 효과를 얻을 수 있습니다.

 

====== source result ======
source [0] : apple
source [1] : banana
source [2] : cherry
====== destination result ======
destination [0] : apple
destination [1] : banana
destination [2] : cherry
destination [3] : kiwi

 

 

 

그런데 여기서 추가적으로 1가지 더 살펴 보아야 하는 부분이 있습니다.

ArrayList  의 Item 으로 객체가(Object) 선언되어 있다면 깊은 복사는 어떻게 동작하게 될까요?

 

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
import java.util.ArrayList;
 
class Fruit {
    private String name;
    private int count;
 
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getCount() {
        return count;
    }
    public void setCount(int count) {
        this.count = count;
    }
}
 
public class CopyTest {
    static ArrayList<Fruit> source = new ArrayList<Fruit>();
    static ArrayList<Fruit> destination = new ArrayList<Fruit>();
    
    public static void initArrayList() {
        if (null != source) {
            source.clear();
            
            String[] names = new String[] {"apple""banana""cherry"};
            for (int i = 0; i < names.length; i++) {
                Fruit f = new Fruit();
                f.setName(names[i]);
                f.setCount(i + 1);
                source.add(f);
            }
        }
 
        if (null != destination) {
            destination.clear();
        }
    }
    
    public static void printArrayList() {
        System.out.println("====== source result ======");
        for (int i = 0; i < source.size(); i++) {
            System.out.println("source["+i+"] name:"+source.get(i).getName());
            System.out.println("source["+i+"] count:"+source.get(i).getCount());
        }
 
        System.out.println("====== destination result ======");
        for (int i = 0; i < destination.size(); i++) {
            System.out.println("destination["+i+"] name:"+destination.get(i).getName());
            System.out.println("destination["+i+"] count:"+destination.get(i).getCount());
        }
    }
 
    public static void main(String[] args) {
        initArrayList();
        
         // TODO : operation
 
        printArrayList();
    }
}
cs

 

코드를 간단히 살펴보면, name 과 count 를 속성으로 갖고 있는 Fruit 클래스가

2 개의 ArrayList 의(source, destination) Item 으로 선언되어 있습니다.

마찬가지로 main() 메소드의 // TODO : operation  위치에서 다음과 같은 2가지 동작을 수행한 후

각각의 ArrayList 가 가지고 있는 값을 모두 출력하게 됩니다. 

1. source 에 있는 내용을 destination 에 복사

2. destination 에 항목을 1개 추가

 

 

동일한 동작을 얕은 복사와 깊은 복사로 적용해 보았습니다.

1. 얕은 복사(shallow copy)      

destination = source;

Fruit f = new Fruit();

f.setName("kiwi");

f.setCount(4);

destination.add(f);

  

<결과>

destination 에만 추가한 kiwi 가 source 에도 추가되어 있음을 확인할 수 있습니다.

shallow copy 는 원본과 복사본 둘 중 한쪽의 수정이 양쪽에 모두 영향을 미치게 됩니다.

 

====== source result ======
source [0] name : apple
source [0] count : 1
source [1] name : banana
source [1] count : 2
source [2] name : cherry
source [2] count : 3
source [3] name : kiwi
source [3] count : 4
====== destination result ======
destination [0] name : apple
destination [0] count : 1
destination [1] name : banana
destination [1] count : 2
destination [2] name : cherry
destination [2] count : 3
destination [3] name : kiwi
destination [3] count : 4

 

2. 깊은 복사(deep copy)     

destination.addAll(source) ; // 또는 destination =(ArrayList<Fruit>)source.clone();

Fruit f = new Fruit();

f.setName("kiwi");

f.setCount(4);

destination.add(f);

  

<결과>

destination 에만 추가한 kiwi 가 source 에는 존재하지 않음을 확인할 수 있습니다.

deep copy 는 원본과 복사본 둘 중 한쪽의 수정이 다른 한쪽에 영향을 미치지 않습니다.

주석으로 표기한 방법으로도 같은 효과를 얻을 수 있습니다.

 

====== source result ======
source [0] name : apple
source [0] count : 1
source [1] name : banana
source [1] count : 2
source [2] name : cherry
source [2] count : 3
====== destination result ======
destination [0] name : apple
destination [0] count : 1
destination [1] name : banana
destination [1] count : 2
destination [2] name : cherry
destination [2] count : 3
destination [3] name : kiwi
destination [3] count : 4

 

 

이것만으로 정말 제대로 된 Fruit 객체에 대한 깊은 복사가 이루어 진 것일까요?

source 의 apple 객체의 count 를 1 에서 10 으로 값을 바꾼다면 destination 에는 영향이 없을까요?

다시 테스트를 진행해 보도록 하겠습니다.

 

* 객체의 깊은 복사(deep copy)

destination.addAll(source) ; // 또는 destination =(ArrayList<Fruit>)source.clone();

Fruit f = destination.get(0);    // "apple"

f.setCount(10);                    // change : 1 -> 10

  

<결과>

분명히 깊은 복사를 진행했는데도 source 와 destination 의 apple 의 count 가 모두 10으로 변경된 것을 확인할 수 있습니다. 결국 두 ArrayList 의 포함된 Fruit 은 같은 객체라는 의미입니다.

 

====== source result ======
source [0] name : apple
source [0] count : 10
source [1] name : banana
source [1] count : 2
source [2] name : cherry
source [2] count : 3
====== destination result ======
destination [0] name : apple
destination [0] count : 10
destination [1] name : banana
destination [1] count : 2
destination [2] name : cherry
destination [2] count : 3

 

이 문제를 해결하기 위해서는 결국 다음과 같은 방법이 필요합니다.

 

* 객체의 깊은 복사(deep copy)

1. Fruit 클래스의 복사 생성자 추가

public Fruit() { }      // 기본 생성자

public Fruit(Fruit f) { // 복사 생성자

   this.name = f.getName();
   this.count = f.getCount();

 }

 

2. main() 메소드에서 객체에 대한 깊은 복사(deep copy) 수행

for (int i = 0; i < source.size(); i++) {
        destination.add(new Fruit(source.get(i)));
}
Fruit f2 = destination.get(0);    // "apple"
f2.setCount(10);                    // change : 1 -> 10

  

<결과>

원본과 복사본 둘 중 한쪽의 수정이 다른 한쪽에 영향을 미치지 않습니다.

이제서야 완전히 독립된 ArrayList 객체 복사가 완료되었습니다.

 

====== source result ======
source [0] name : apple
source [0] count : 1
source [1] name : banana
source [1] count : 2
source [2] name : cherry
source [2] count : 3
====== destination result ======
destination [0] name : apple
destination [0] count : 10
destination [1] name : banana
destination [1] count : 2
destination [2] name : cherry
destination [2] count : 3

 

Posted by maze1008
,

새로운 모든 언어/플랫폼을 접할 때 개발 환경을 설정하고

 

가장 먼저 하게 되는 작업이 "Hello World 출력하기" 일 것입니다.

 

개발 환경 설정 + "Hello World 출력하기" 를 모두 마쳤다면 그 언어의 대해 50% 이상의 벽을 넘었다는 의미처럼 느껴질 정도로 말입니다.

 

자! 그럼 이제 새로운 프로젝트를 생성해서 Hello World 를 출력해 보도록 하겠습니다.

 

혹시 안드로이드 개발환경이 아직 완료되지 않으셨다면 아래 포스팅을 참고하여 주시기 바랍니다.

안드로이드 개발환경 구축하기

 

 

 

1. 프로젝트 생성하기

 

 

이클립스를 실행합니다.

File 메뉴 > New > Project 를 선택합니다.

 

 

 

새로운 프로젝트를 생성하기 위해 다이얼로그가 나타나는 것을 확인할 수 있습니다.

Android 폴더 > Android Application Project 선택 > Next 버튼을 클릭합니다.

 

 

 

생성하고자 하는 Application / Project / Package Name 을 순서대로 입력하고

Minimum Required SDK(지원하고자 하는 최소 버전), Target SDK(타켓 버전), Complie With(프로젝트 컴파일하여 빌드할 때 사용할 버전)을 순서대로 선택합니다.

 

현재 Hello world 프로젝트를 간단하게 실행하기 위해서는 Application Name 만 입력해 주셔도 됩니다.

Next 버튼을 클릭합니다.

 

 

다음에 나타나는 화면들에서는 Next or Finish 버튼을 클릭하여 프로젝트 생성을 완료합니다.

(프로젝트에 대한 상세한 설정을 위해 필요한 부분이지만 대부분 수정을 하지 않습니다.)

 

 

 

 

 

 

 

다이얼로그가 사라지고 좌측 화면에 Application Name 으로 입력했던 HelloWorld 프로젝트가 생성된 것을 확인할 수 있습니다.

 

 

 

2. 프로젝트 실행하기

 

프로젝트(HelloWorld 어플리케이션) 을 실행하기 위해서 AVD 를 생성 및 실행합니다.

안드로이드 AVD 생성 및 옵션 조정

 

 

 

좌측 화면에서 HelloWorld 프로젝트를 선택하고

상단의 툴바에 있는 시작 버튼 > Run As > Android Application 을 선택합니다.

 

 

 

미리 실행해 놓았던 AVD(에뮬레이터)에 HelloWorld 어플리케이션이 실행되어 화면에 나타납니다.

 

실제 스마트폰에 연결해서 테스트 하고 싶다면 AVD(에뮬레이터) 대신 스마트폰을 PC 에 연결하시면 됩니다.

PC 와 스마트폰 연결하기 (ADB 사용)

 

 

만약 PC 에 스마트폰과 AVD(에뮬레이터) 등이 동시에 연결되어 있다면

어떤 디바이스에서 HelloWorld 어플리케이션을 실행할 것인지 선택하기 위한 다이얼로그가 나타나며 (Android Device Chooser) 그곳에서 원하는 디바이스를 선택하시면 됩니다.

 

Posted by maze1008
,

자바에서는 Random 클래스와 Math 클래스를 사용하여 편리하게 random value 를 생성할 수 있습니다.

자바 랜덤함수(Java Random)

 

 

그러나 랜덤 문자열(random string) 을 만들기 위해서는 추가적으로 간단한 구현이 필요합니다.

지금부터는 random string 을 만들기 위한 방법에 대해 설명하도록 하겠습니다.

 

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
import java.util.Random;
 
public class RandomString {
    private static final char[] chars;
    static {
        StringBuilder buffer = new StringBuilder();
        for (char ch = '0'; ch <= '9'; ++ch)
            buffer.append(ch);
        for (char ch = 'a'; ch <= 'z'; ++ch)
            buffer.append(ch);
        for (char ch = 'A'; ch <= 'Z'; ++ch)
            buffer.append(ch);
        chars = buffer.toString().toCharArray();
    }
 
    public static String random(int length) {
        if (length < 1)
            throw new IllegalArgumentException("length < 1: " + length);
 
        StringBuilder randomString = new StringBuilder();
        Random random = new Random();
        
        for (int i = 0; i < length; i++) {
            randomString.append(chars[random.nextInt(chars.length)]);
        }
        return randomString.toString();
    }
 
    public static void main(String[] args) {
        System.out.println(random(10));
    }
}
cs

 

위의 random() 메소드는 글자의 길이(length) 를 파라미터로 입력 받아

원하는 크기의 random string 생성하고 있습니다.

 

chars 배열을 통해 원하는 문자(숫자, 소문자, 소문자)들을 기초로 하여

Random 클래스의 nextInt() 메소드에서 발생시키는 위치의 배열 값을 차곡차곡 쌓아

지정된 길이 만큼의 string 을 생성해서 반환합니다.

 

이외에도 "~!@#$%^&*()_+{}|\\\"`;:'<>?,./=-[]" 와 같은 특수 기호들을 포함할 수도 있습니다.

 

<출력>

3ifL5KImXd

 

 

추가적으로 stackoverflow 를 통해서 더 다양한 방법을 확인 할 수 있습니다.

 

 

Posted by maze1008
,