달력

112017  이전 다음

  •  
  •  
  •  
  • 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
  •  
  •  

ArrayList, CopyOnWriteArrayList, LinkedList, Vector, CheckedList,


ArrayList

멤버 변수에는 저장된 데이타의 갯수 size와 데이타를 담는(C에서 포인터처럼 가리키는) Object elementData[]가

정의되어 있다.


넉넉하게 elementData를 잡아놨다가 저장 공간이 부족하면 grow를 호출한다.

또한 elementData 중간에 데이타를 추가하거나, 제거할때는 그 뒷부분의 배열을 앞쪽으로 당기거나 뒤쪽으로 미는
동작을 수행한다.        마지막에 위치한  데이타를 삭제하고 추가시 elementData의 이동은 없다.


여기까지가 기본적인 데이타 추가/수정/삭제 얘기고 ArrayList 보면서 재미진 부분에 대해(지극히 주관적입니다;;) 얘기한다.


* removeAll, retailAll method  사실 이런게 있는지 처음 알았다... A.removeAll(B)는 A에 A-B의 데이타가 남고

A.retailAll(B)는 A와 B의 교집합 데이타가 A에 남는다.


* 데이타를 추가/삭제시 modCount++를 수행하는데 그 이유는 writeObject 에 있다.

writeObject 를 보면 Object를 쓰기전에 modCount를 저장해놨다가 쓰기 작업이 완료된 후, 쓰기 작업 중간에
추가/삭제 작업이 진행됐는지 체크한다.

* sublist가 있는데 사용법은 아래 url에 잘 나와있다.

http://stackoverflow.com/questions/6189704/how-to-take-a-valid-sublist-in-java  
전체가 아닌 부분에 대해서만 작업을 하고 싶을때 사용하면 좋다고 한다.



Vector에서 ArrayList와 가장 큰 차이점이 public method들이 synchronized를 사용한다는 점이다. (생성자와 enumeration 제외) 그래서 writeObject에서는 사용하지 않는다.


Stack은 Vector를 상속하고 5개의 method가 추가되었다. LIFO 동작을 위해 필요한 method들이다.
javadoc에서 더 확실한 LIFO를 사용하고싶다면 Deque를 사용하라고 한다.


LinkedList는 배열이 아닌 포인터(이렇게 말해도 되려나..)를 이용해 양방향 링크드 리스트를 구현하였다.

synchronized가 아니고, 다른 자료구조와는 다르게 modCount를 사용하지 않는다. 그래서 writeObject시 쓰는 중간에

추가/수정/삭제가 실행되도 에러가 발생되지 않는다. 


CopyOnWriteArrayList는 ArrayList를 thread-safe하게 만든 자료구조다.
멤버 변수로 ReentrantLock lock을 갖고있고, 추가/수정/삭제시 lock을 건다. 그리고 clone 시에는 얕은복사를 하고,
추가/수정/삭제시에 데이타를 갖고있는 array 복사를 한다.
추가/수정/삭제시 매번 복사가 발생하므로 데이타 변경이 빈번한곳에서는 쓰면 안될것같다.

저작자 표시 비영리
신고
Posted by 오산돌구
TAG Java

기초가 많이 부족하다는 것을 느껴서 다시 공부려고 하다가 JCF라는걸 알게되었습니다.

자바는 자료구조가 다 구현되어서 마냥 좋다고 쓰기만 했지 이런게 있는지도 몰랐네요.  

꾸준히 할지는...모르겠지만 한번 다 보도록 몸부림 쳐보려고요 : )   

앞으로 글은 인터넷의 자료들을 제 나름대로 정리하는 식으로 진행하려고 합니다.

틀린 부분이 있으면 알려주세요. 혼자 하는거라 이게 맞는건줄 알아요.....ㅜ,ㅜ

================================================


java collection framework를 치면 기본적으로 다음과 같은 그림이 나온다.

 

Map은 Collection과 연관이 없는데 그 이유에  대해서 이렇게 설명하고 있다.(http://howtodoinjava.com/2013/07/09/useful-java-collection-interview-questions/#why_map_not_extend_collection)

Map은 Collection과는 다른 구조이기 때문이다. Collection에는 add(Object o) 함수가 있는데 Map은 key-value 구조

이므로 다르다. 그리고 Map은 keySet, valueSet, entrySet함수가 있는데 Collection에는 지원하지 않는다.


List, Queue가 어떻게 구현되었는지 알아본다.


마지막으로 http://howtodoinjava.com/2013/07/09/useful-java-collection-interview-questions/

소개한 질문들을 소스를 보면서 파악해본다.


Map은 삼실청년 블로그에 잘 설명되어있어서 패스하고 Set은 Map을 멤버 변수로 가지고 동작하는 자료구조라 패스!!


ref : http://howtodoinjava.com/2013/07/09/useful-java-collection-interview-questions/#what_is_collection_in_java

http://www.cse.ohio-state.edu/software/2231/web-sw2/extras/slides/31.Java-Collections-Framework.pdf

저작자 표시 비영리
신고
Posted by 오산돌구
TAG Java
에 선임이 DB 데이타를 가져오는 java 프로그램을 선임이 만들었는데, oracle에서만 실행이 되었습니다.

그래서 MySql, Oracle, MSSql에서 유동적으로 동작하는 프로그램을만들어보자 해서 만들어보았고 혹시나~!!!
정말 혹시나~!! 이것이 필요한 사람이 있을지도 모른다는 생각에 이렇게 글을 올립니다.

이것의 주용도는 C로 개발하는 프로그램에서 DB의 데이타를 가져오는 기능이 있어야하는데 이 부분을 담당합니다.

C에서는 아래와 같이 DB 데이타를 가공 및 저장 합니다.


실행 방법은 다음과 같습니다.

java -jar DBManager2010.jar [config path] [SQL Query] [option -c|-f|-u|-uf|-unf|-d]  [input Filepath]

---------------------------

SQL>desc dbtest

  id       Number(20)

name varchar(30)

 grade  Number(20)

----------------------------

========================

input.txt


name    id    grade

날리지큐브    1    00111
검색연구소    2    1733
강한구    3    1231
서서희    4    3214321
이주호    5    3531

========================

각 옵션에 대한 예제

java -jar DBManager2010.jar mssqlDB.conf  "select * from DBTEST" -c

java -jar DBManager2010.jar mssqlDB.conf  "select * from DBTEST" -f c:\getdb.txt

java -jar DBManager2010.jar mssqlDB.conf  "delete from DBTEST" -d

java -jar DBManager2010.jar mssqlDB.conf  "insert into DBTEST values('id', 'name', 'grade')" -u

java-jar DBManager2010.jar mssqlDB.conf  "insert into DBTESTvalues('<#id>;', <#'name>;', '<#grade>;')" -ufinput.txt

java-jar DBManager2010.jar mssqlDB.conf  "insert into DBTESTvalues('<#id>;', <#'name>;', '<#grade>;')" -unf input.txt       

(-uf와 같지만 input.txt에서 필드명이 없이 데이타만 존재, 예제의 경우 id, name, grade순으로 차례대로 데이타가 나열되어있다고 가정하고 쿼리문 생성및 실행)


주의사항 

SQL은 "select~~~" 과 같이 쌍따옴표로 감싸줘야합니다.

SQL  마지막에 세미콜론은 하지 않습니다.

insert나 update할때 실제 데이타를 입력할때는 쌍따옴표가 아니라 혿따옴표로 해야합니다.

간단한 쿼리문 실행을 위해 만들었기 때문에 프로시져나 복잡한 조인은 안됩니다.

사용하시고 버그나 실행이 안되는 부분, 이거 됐으면 좋겠다~ 라는 부분이 있으면 말씀해주세요.
개발 입문 단계라 많이 부족합니다. 좋은 의견 부탁드려요~~

DBManager2010.jar

KC_DBManager.zip



======================2010.12.08 추가사항==================
네가지가 수정되었습니다.         필드별 인코딩, null 데이타 입력, argument 변경 기능 추가입니다.

우선 필드별 인코딩을 보겠습니다.
@e는 euc-kr로 인코딩 @u는 utf-8로 인코딩한후 데이타를 삽입합니다.
인코딩할 필드 데이타  <#~~~>;  에서 세미콜론 다음에 @e, @u를 적어주시면 됩니다.




다음은 아래와 같은 데이타를 입력할때 null로 데이타를 입력하게 됩니다 전에는 이건 가정을 안하고 진행을 했네요;;
아래와 같이 필드가 5개인데, 데이타가 중간중간 비는경우. . . 에 대해 처리를 했습니다.




다음은 argument중 option을 없앴습니다. 기존에는 실행문에서 SQL문 다음에 -c, -u, -uf같은 옵션을 주었지만, 이젠 안줘도 됩니다.  아래와 같이 DML문을 실행하면 되겠습니다.

KC_DBManager2010.jar

소스는 안올릴거에요. 관심 좀 달라는 의미......ㅋㅋㅋㅋㅋㅋㅋ
저작자 표시 비영리
신고
Posted by 오산돌구
TAG Java

요새 자바로 개발을 하고있는데 제목과 같이 두개를 사용할 기회가 있었다.

시시하지만 그저 남기고 싶어서 이렇게 글을 쓴다.

split
public class test {	
public static void main(String[] args) {	
		String input = "kang#@sdasfd#@asasf#@#@asdfs#@#@";
		String name[];
		name = input.split("#@");
		for (String buf: name){			
			System.out.println("split:" + buf);
		}	
	}
}
실행하면 결과가 name이 6개 할당될줄알았는데 아니었다.


마지막은 처리하지 않는다~
굳이 마지막은 안한다는 연산을 왜 했는지 궁금하다....(이부분 아시는 분있으시면 알려주세요~~)


MessageFormat
팀에서 사용하기위해 기존에 DB데이타 가져오는 모듈을 조금 개선하는 작업을 하고있다.
아래와 같은 기능을 하고있다.
java -jar DBManager2010.jar oracleDB.conf "insert into DBTEST values('<#id>;', '<#name>;', '<#grade>;')" -uf input.txt

input.txt의 내용


이렇게 하면
실행되는 쿼리문은  아래와 같다.
insert into DBTEST values('1', '날리지큐브', '00111')
insert into DBTEST values('2', '검색연구소', '1733')
......
.......
insert into DBTEST values('5', '이주호', '3531')
<#~~~>; 이부분을 %s로 치환을 한후 String배열에 실제 데이타를 순서에 맞게 저장하는걸로 만들기로했다.

만들고 보니.....음.......만약에 사용자가 <#~~>;사용을 30개정도 한다고 하면?
. . . 무식해 보인다.

MessageFormat 이 생각이 나서아래와 같이 작성했다.
오~~~ 좋다 ㅋㅋㅋㅋ
%s를 바꾸는것을 필드 위치번호로 변경만 해주면된다.
'로 하면 문자로 인식하기때문에 '' (' 두개)로 해야한다는것에 주의~!!ㅋㅋ


다시 한번 느끼지만 삶에 도움이 되지 않는 배움은 없다. 그리고 배움은 실제 경험해볼때 빛을 발하는것같다.

저작자 표시 비영리
신고
Posted by 오산돌구
TAG Java
Java로 암/복호화할 일이 생겨서 개발하다가 Base64Decoder/Encoder사용하니까 에러가 나는것이었다.


자 해결방법은 기본으로 설정된 JRE Library를 삭제했다가 다시추가하면 된다;;
이유는 뭐지.....아놔.....허허

1. 해당 프로젝트의 Properties 클릭


2. Libraries 탭을 클릭하고 기본으로 있는 JRE System Library를 Remove
그리고 Add Library클릭~!!



3. JRE System Library 추가~!!


4. 쨔잔~!! 멀쩡합니다. : )


도움이 되었으면 좋겠네요.
근데 왜 이런건지 아시는분은 조언 부탁합니다~~ ;;

참조사이트 : http://forums.dzone.com/eclipse/384-access-restriction-problems.html
저작자 표시 비영리
신고
Posted by 오산돌구
TAG Java

MessageFormat

개발하면서 2009.11.03 23:42

필요는 사람을 집중하게 만든다.

C에서 sprintf기능을 하는게 Java에 있는지 알아보던중, MessageFormat이라는것을 알게되었다.

Java에서는 String의 개념이 있어서 '+'연산으로 다 가능해 그다지 쓸모는 없지만.....;; 그래도 알면 좋다는 신념아래

알아보기로 했다.


//C의 sprintf는
char form[50] = "age : %d, area : %s\n";
char output[200];
sprintf(output, form, 26, "오산");
printf("output : %s\n", output);

//뭐 이런식인데 Java의 MessageFormat은 String form = "age: {0}, area: {1}"; System.out.println(MessageFormat.format(form, new Object[]{age, area}));

 

다음과 같이 사용할수 있다.

import java.text.MessageFormat;
import java.util.Date;
import java.io.*;

public class Test{ // private static final String patternSimplifiedData = "내이름은 {0} 이고 나이는 {1}이다. 사는곳은 {2}이며 {3}를 꿈꾸고 있다."; // public static void main(String[] args) // { // String area = "오산"; // System.out.println(MessageFormat.format(patternSimplifiedData, // new Object[] { "강한구", "19", area, "간지나는 개발자"})); // } public static void main(String[] args) { Object[] arguments = { new Integer(7), new Date(System.currentTimeMillis()), "a disturbance in the Force" };
String result = MessageFormat.format( "At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.", arguments); System.out.println("result :" + result);
} }

출력 :


더 많은 예제는 아래에 있다.

출처 : http://java.sun.com/j2se/1.4.2/docs/api/java/text/MessageFormat.html

신고
Posted by 오산돌구
TAG Java
예전부터 조사해봐야지 생각만하다가 했음

나름대로 정리한것

우선 Java의 메모리 구조는 Eden, Survivor 1/2, Old, Perm으로 되어있다.

Eden은 객체가 생성되면 저장되는곳이고,

Survivor 1/2 MinorGC가 일어날때마다 Eden에서 이동되는 공간이다.

Old Survivor영역에서 오래된 객체가 저장되는 곳이다.

마지막으로 Perm Code가 저장되는 곳으로서 실행이후 일정한 수치를 유지하므로 신경안써도된다.

 

우선 맨 처음 Application이 실행되면, 객체가 Eden에 저장이 된다. 그러다가 GC가 발생하면 Eden에 있던 객체중 Alive된 객체는 Survivor1로 이동을 하고, Eden에 있는 나머지는 clear된다.

중간에 객체가 생성이되고 Eden에 저장이되다가 GC가 실행이되면 Eden Survivor1 Alive된 객체가 Survivor2로 이동되고 Eden, Survivor1 clear된다.

다시 한번 GC가 실행되면 Eden, Survivor2에 있는 Alive된객체는 Survivor1에 이동되고 나머지는 Clear된다. 계속 반복을한다

위에서 수행되는 GC MinorGC라고한다. (속도 빠름, 자주일어남)

 

MinorGC가 수행하는 가운데 Survivor에 있는 객체중 오래된 객체는 Old영역으로 이동된다.

 

Old영역의 GCMark & Compact 알고리즘을 사용한다. Old에 있는 모든 객체를 따라가면서 reference가 연결되지않은 객체를 Mark한뒤, Mark가 끝나면 Mark된객체는 삭제한다.

이것을 Full GC라고 한다. (속도느림, 순간적으로 application멈춤)




https://www.ibm.com/developerworks/java/library/j-jtp11253/

확실한 건데 해석하려면 반나절이니. . . 일단 프린트 고고싱 

의문점 : 그럼 오래된객체인지는 어떻게 하는지, Alive의여부는 어떻게 정해지는 것인지

JVM GC와 메모리 Tuning.pdf


이 글은 저의 이해 및 정리한 것이므로 사실과 다를 수 있습니다.
틀린점은 지적해주시면 감사하겠습니다.
신고
Posted by 오산돌구
TAG Java

Java File I/O

개발하면서 2009.06.24 10:11

요새 검색엔진을 공부하고 있어서 그런지(핑계...ㅋ)블로그가 뜸했다.
여태까지 개발하면서 의문점이 들었던것들 하나하나 공부해보자

byte 단위로 읽은 File I/O 에서 skip, seek은 \r\n까지 계산해서 이동한다
우선 검색엔진 개발하면서 파일을 다뤄야되는데
바이트 단위로 읽을경우, file_size는  다음과 같이 구해야한다고 한다. (skip을하기 위해서)

try
		{
			BufferedReader reader = new BufferedReader	(new FileReader(filename));
			while((str = reader.readLine()) != null)
			{
				doc.append(str);
//				line = str.getBytes();
//				F_Size = F_Size + line.length+2;
				F_Size = F_Size + str.length()+2;		// \r\n부분
				System.out.println("str : " + str + ",  file_size : " + F_Size);
				if(str.equals("<doc>"))
				{
					doc_loc.add(F_Size-7);
					doc_begin = F_Size-7;
					branch_end = 0;
					branch_begin = 0;
				}

carriage return 때문이라고 하는데  이에 대해서는 아래 완전 이해잘되게 설명했으니 패스
http://mwultong.blogspot.com/2006/06/line-feed-lf-carriage-return-cr.html

정말 윈도우랑 리눅스랑 텍스트 표현방식이 다른지 알아보자
soundex.c는 리눅스에서
dong1.xml은 윈도우에서 작성한 파일이다.

더보기




두번째 File I/O 에서 byte, String의 length 차이를 알아보자


import java.io.*;
public class Test
{
	public static void main(String[] args)
	{
		try
		{
			BufferedReader br = new BufferedReader(new FileReader("dong1.xml"));
			
			String str = new String();
			byte[] buf = new byte[100];
			
			while((str = br.readLine()) != null)
			{
				System.out.println("Input Line : " + str);
				System.out.println("str : "+str.length());
				buf = str.getBytes();
				System.out.println("buf : " +buf.length);
			}
		}
		catch(IOException e)
		{
			e.printStackTrace();
		}
	}
}
String에서는 한글, 영어 다 1로 간주하고 byte 에서는 한글 2, 영어 1로 간주한다.
유니코드에서 한글은 3바이트라고 한걸 본거같은데 다시 자세히 공부해야 할것같다. 헷갈리네....
개행문자는 계산하지 않으므로 주의하자

신고
Posted by 오산돌구
TAG Java
<SPAN id=tx_marker_caret></SPAN>  String str = new String ("Stanford  ");
     str += "Lost!!";
바이트 코드로 변환하면 아래와 같다.

String '+'연산을 할때 임시저장소 StringBuffer을 만든뒤 append를 한 후 다시 String으로 변환하는 작업을 한다.

바이트 코드로 변환하면 다음과 같다

StringBuffer str = new StringBuffer ("Stanford ");str.append("Lost!!");

StringBuffer는 append연산을 위해 임시저장소도 사용하지 않고 변환작업 없이 수행을 한다.

StringBuffer를 사용하라는 결론이었다.

자료 : http://www.javaworld.com/javaworld/jw-03-2000/jw-0324-javaperf.html



여기에서는 용도에 맞게 사용하라는 것.

String과 StringBuffer 연산 시간을 비교하는 소스의 잘못을 짚어주고, StringBuffer의 Array doubling이라는 개념을 설명해주었다.

여기서는 쿼리문같이 한번의 대입연산에서 '+'연산으로 긴 문자열을 만들경우는 String을

루프를 돌거나 중간중간 추가하려면 StringBuffer를 사용하라는 말을 한다.

자료 : http://youngrok.com/wiki/wiki.php/StringVsStringBuffer



이 글은 저의 이해 및 정리한 것을 적은것이므로 실제와 다를 수 있습니다.

신고
Posted by 오산돌구
TAG Java

JAVA I/O

개발하면서 2009.04.07 19:33

사용자입력 I/O

String File I/O

byte File I/O입출력

한글깨지는 고치기

더 많은 I/O를 보려면 http://java.sun.com/docs/books/tutorial/essential/io/scanning.html http://java.sun.com/docs/books/tutorial/essential/io/scanning.html
신고
Posted by 오산돌구
TAG Java