Last active
August 30, 2015 04:20
-
-
Save openbooks/11553177 to your computer and use it in GitHub Desktop.
配列のShallwCopyとDeepCopyの実現方法 ref: http://qiita.com/Koo_zZ/items/269105e59e158ea9732d
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.sample.koozz; | |
import java.util.ArrayList; | |
import java.util.Collection; | |
import java.util.List; | |
public class Client { | |
// Stringをリスト | |
static List<String> ranger = new ArrayList<String>() { | |
private static final long serialVersionUID = 1L; | |
{ | |
add("アカレンジャー"); | |
add("アオレンジャー"); | |
add("キレンジャー"); | |
add("ピンクレンジャー"); | |
add("ミドレンジャー"); | |
} | |
}; | |
public static void main(String[] args) { | |
// shallow copy | |
Collection<String> copy1 = ranger; | |
ranger.set(0, "Hoge"); | |
System.out.println(ranger + "コピー元"); | |
System.out.println(copy1 + "コピー先"); | |
// deep copy | |
Collection<String> copy2 = new ArrayList<>(ranger); | |
ranger.set(1, "Fuge"); | |
System.out.println(ranger + "コピー元"); | |
System.out.println(copy2 + "コピー先"); | |
// [Hoge, アオレンジャー, キレンジャー, ピンクレンジャー, ミドレンジャー]コピー元 | |
// [Hoge, アオレンジャー, キレンジャー, ピンクレンジャー, ミドレンジャー]コピー先 | |
// [Hoge, Fuge, キレンジャー, ピンクレンジャー, ミドレンジャー]コピー元 | |
// [Hoge, アオレンジャー, キレンジャー, ピンクレンジャー, ミドレンジャー]コピー先 | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.sample.koozz; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.List; | |
public class Client { | |
// Stringをリスト | |
static List<String> ranger = new ArrayList<String>() { | |
private static final long serialVersionUID = 1L; | |
{ | |
add("アカレンジャー"); | |
add("アオレンジャー"); | |
add("キレンジャー"); | |
add("ピンクレンジャー"); | |
add("ミドレンジャー"); | |
} | |
}; | |
// Hogeをリスト | |
static List<Hoge> hoges = new ArrayList<Hoge>() { | |
private static final long serialVersionUID = 1L; | |
{ | |
add(new Hoge("赤戦闘員")); | |
add(new Hoge("青戦闘員")); | |
add(new Hoge("黄戦闘員")); | |
add(new Hoge("桃戦闘員")); | |
add(new Hoge("緑戦闘員")); | |
} | |
}; | |
public static void main(String[] args) { | |
// リストから配列 to DeepCopy | |
String[] rangerAry = ranger.toArray(new String[0]); | |
ranger.set(0, "赤レンジャー"); // 新しいインスタンス | |
System.out.println(ranger); | |
System.out.println(Arrays.toString(rangerAry)); | |
// [赤レンジャー, アオレンジャー, キレンジャー, ピンクレンジャー, ミドレンジャー] ------> コピー元 | |
// [アカレンジャー, アオレンジャー, キレンジャー, ピンクレンジャー, ミドレンジャー] ----> コピー先 | |
// リストから配列 to DeepCopy | |
Hoge[] hhgg = hoges.toArray(new Hoge[0]); | |
hoges.set(0, new Hoge("朱戦闘員")); // 新しいインスタンス | |
System.out.println(hoges); | |
System.out.println(Arrays.toString(hhgg)); | |
// [Hoge [piyo=朱戦闘員], Hoge [piyo=青戦闘員], Hoge [piyo=黄戦闘員], Hoge [piyo=桃戦闘員], Hoge [piyo=緑戦闘員]] ---> コピー元 | |
// [Hoge [piyo=赤戦闘員], Hoge [piyo=青戦闘員], Hoge [piyo=黄戦闘員], Hoge [piyo=桃戦闘員], Hoge [piyo=緑戦闘員]] ---> コピー先 | |
// ---------- | |
// リストから配列 リストに追加後に内容を変更 to DeepCopy | |
String target = "ホワイトレンジャー"; | |
ranger.add(target); | |
String[] rangerAry2 = ranger.toArray(new String[0]); | |
target = "ムラサキレンジャー"; // インスタンスの使い回し | |
ranger.set(ranger.size()-1, target); | |
System.out.println(ranger); | |
System.out.println(Arrays.toString(rangerAry2)); | |
// [赤レンジャー, アオレンジャー, キレンジャー, ピンクレンジャー, ミドレンジャー, ムラサキレンジャー] ---> コピー元 | |
// [赤レンジャー, アオレンジャー, キレンジャー, ピンクレンジャー, ミドレンジャー, ホワイトレンジャー] ---> コピー先 | |
// リストから配列 リストに追加後に内容を変更 to DeepCopy?????? >> shallow Copy | |
Hoge hoge = new Hoge("白戦闘員"); | |
hoges.add(hoge); | |
Hoge[] hhgg2 = hoges.toArray(new Hoge[0]); | |
hoge.setPiyo("ハイハイ戦闘員"); // インスタンスの使い回し | |
hoges.set(hoges.size()-1, hoge); | |
System.out.println(hoges); | |
System.out.println(Arrays.toString(hhgg2)); | |
// !!!!! コピー先まで変わってる Shallow Copy | |
// [Hoge [piyo=朱戦闘員], Hoge [piyo=青戦闘員], Hoge [piyo=黄戦闘員], Hoge [piyo=桃戦闘員], Hoge [piyo=緑戦闘員], Hoge [piyo=ハイハイ戦闘員]] | |
// [Hoge [piyo=朱戦闘員], Hoge [piyo=青戦闘員], Hoge [piyo=黄戦闘員], Hoge [piyo=桃戦闘員], Hoge [piyo=緑戦闘員], Hoge [piyo=ハイハイ戦闘員]] | |
} | |
static class Hoge { | |
private String piyo; | |
/** | |
* @param piyo | |
*/ | |
private Hoge(String piyo) { | |
super(); | |
this.piyo = piyo; | |
} | |
/** | |
* @return piyo | |
*/ | |
public String getPiyo() { | |
return piyo; | |
} | |
/** | |
* @param piyo | |
* セットする piyo | |
*/ | |
public void setPiyo(String piyo) { | |
this.piyo = piyo; | |
} | |
/* (非 Javadoc) | |
* @see java.lang.Object#toString() | |
*/ | |
@Override | |
public String toString() { | |
StringBuilder builder = new StringBuilder(); | |
builder.append("Hoge [piyo="); | |
builder.append(piyo); | |
builder.append("]"); | |
return builder.toString(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.sample.koozz; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.List; | |
public class Client { | |
// Stringをリスト | |
static List<String> ranger = new ArrayList<String>() { | |
private static final long serialVersionUID = 1L; | |
{ | |
add("アカレンジャー"); | |
add("アオレンジャー"); | |
add("キレンジャー"); | |
add("ピンクレンジャー"); | |
add("ミドレンジャー"); | |
} | |
}; | |
// Hogeをリスト | |
static List<Hoge> hoges = new ArrayList<Hoge>() { | |
private static final long serialVersionUID = 1L; | |
{ | |
add(new Hoge("赤戦闘員")); | |
add(new Hoge("青戦闘員")); | |
add(new Hoge("黄戦闘員")); | |
add(new Hoge("桃戦闘員")); | |
add(new Hoge("緑戦闘員")); | |
} | |
}; | |
public static void main(String[] args) { | |
// リストから配列 to DeepCopy | |
String[] rangerAry = ranger.toArray(new String[0]); | |
ranger.set(0, "赤レンジャー"); // 新しいインスタンス | |
System.out.println(ranger); | |
System.out.println(Arrays.toString(rangerAry)); | |
// [赤レンジャー, アオレンジャー, キレンジャー, ピンクレンジャー, ミドレンジャー] ------> コピー元 | |
// [アカレンジャー, アオレンジャー, キレンジャー, ピンクレンジャー, ミドレンジャー] ----> コピー先 | |
// リストから配列 to DeepCopy | |
Hoge[] hhgg = hoges.toArray(new Hoge[0]); | |
hoges.set(0, new Hoge("朱戦闘員")); // 新しいインスタンス | |
System.out.println(hoges); | |
System.out.println(Arrays.toString(hhgg)); | |
// [Hoge [piyo=朱戦闘員], Hoge [piyo=青戦闘員], Hoge [piyo=黄戦闘員], Hoge [piyo=桃戦闘員], Hoge [piyo=緑戦闘員]] ---> コピー元 | |
// [Hoge [piyo=赤戦闘員], Hoge [piyo=青戦闘員], Hoge [piyo=黄戦闘員], Hoge [piyo=桃戦闘員], Hoge [piyo=緑戦闘員]] ---> コピー先 | |
// ---------- | |
// リストから配列 リストに追加後に内容を変更 to DeepCopy | |
String target = "ホワイトレンジャー"; | |
ranger.add(target); | |
String[] rangerAry2 = ranger.toArray(new String[0]); | |
target = "ムラサキレンジャー"; // インスタンスの使い回し | |
ranger.set(ranger.size()-1, target); | |
System.out.println(ranger); | |
System.out.println(Arrays.toString(rangerAry2)); | |
// [赤レンジャー, アオレンジャー, キレンジャー, ピンクレンジャー, ミドレンジャー, ムラサキレンジャー] ---> コピー元 | |
// [赤レンジャー, アオレンジャー, キレンジャー, ピンクレンジャー, ミドレンジャー, ホワイトレンジャー] ---> コピー先 | |
// リストから配列 リストに追加後に内容を変更 to DeepCopy?????? >> shallow Copy | |
Hoge hoge = new Hoge("白戦闘員"); | |
hoges.add(hoge); | |
Hoge[] hhgg2 = hoges.toArray(new Hoge[0]); | |
hoge.setPiyo("ハイハイ戦闘員"); // インスタンスの使い回し | |
hoges.set(hoges.size()-1, hoge); | |
System.out.println(hoges); | |
System.out.println(Arrays.toString(hhgg2)); | |
// !!!!! コピー先まで変わってる Shallow Copy | |
// [Hoge [piyo=朱戦闘員], Hoge [piyo=青戦闘員], Hoge [piyo=黄戦闘員], Hoge [piyo=桃戦闘員], Hoge [piyo=緑戦闘員], Hoge [piyo=ハイハイ戦闘員]] | |
// [Hoge [piyo=朱戦闘員], Hoge [piyo=青戦闘員], Hoge [piyo=黄戦闘員], Hoge [piyo=桃戦闘員], Hoge [piyo=緑戦闘員], Hoge [piyo=ハイハイ戦闘員]] | |
} | |
static class Hoge { | |
private String piyo; | |
/** | |
* @param piyo | |
*/ | |
private Hoge(String piyo) { | |
super(); | |
this.piyo = piyo; | |
} | |
/** | |
* @return piyo | |
*/ | |
public String getPiyo() { | |
return piyo; | |
} | |
/** | |
* @param piyo | |
* セットする piyo | |
*/ | |
public void setPiyo(String piyo) { | |
this.piyo = piyo; | |
} | |
/* (非 Javadoc) | |
* @see java.lang.Object#toString() | |
*/ | |
@Override | |
public String toString() { | |
StringBuilder builder = new StringBuilder(); | |
builder.append("Hoge [piyo="); | |
builder.append(piyo); | |
builder.append("]"); | |
return builder.toString(); | |
} | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.sample.koozz; | |
import java.util.ArrayList; | |
import java.util.Collection; | |
import java.util.List; | |
public class Client { | |
// Stringをリスト | |
static List<String> ranger = new ArrayList<String>() { | |
private static final long serialVersionUID = 1L; | |
{ | |
add("アカレンジャー"); | |
add("アオレンジャー"); | |
add("キレンジャー"); | |
add("ピンクレンジャー"); | |
add("ミドレンジャー"); | |
} | |
}; | |
public static void main(String[] args) { | |
// shallow copy | |
Collection<String> copy1 = ranger; | |
ranger.set(0, "Hoge"); | |
System.out.println(ranger + "コピー元"); | |
System.out.println(copy1 + "コピー先"); | |
// deep copy | |
Collection<String> copy2 = new ArrayList<>(ranger); | |
ranger.set(1, "Fuge"); | |
System.out.println(ranger + "コピー元"); | |
System.out.println(copy2 + "コピー先"); | |
// [Hoge, アオレンジャー, キレンジャー, ピンクレンジャー, ミドレンジャー]コピー元 | |
// [Hoge, アオレンジャー, キレンジャー, ピンクレンジャー, ミドレンジャー]コピー先 | |
// [Hoge, Fuge, キレンジャー, ピンクレンジャー, ミドレンジャー]コピー元 | |
// [Hoge, アオレンジャー, キレンジャー, ピンクレンジャー, ミドレンジャー]コピー先 | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.sample.koozz; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.Collection; | |
import java.util.List; | |
public class DataObject { | |
private String id; | |
private List<String> list = new ArrayList<>(); | |
/** | |
* | |
* @see java.util.List#clear() | |
*/ | |
public void clear() { | |
list.clear(); | |
} | |
/** | |
* @return list | |
*/ | |
public List<String> getList() { | |
return list; | |
} | |
/** | |
* @param c | |
* @return | |
* @see java.util.List#addAll(java.util.Collection) | |
*/ | |
public boolean addAll(Collection<? extends String> c) { | |
return list.addAll(new ArrayList<>(c)); | |
} | |
/** | |
* @return | |
* @see java.util.List#toArray() | |
*/ | |
public Object[] toArray() { | |
return list.toArray(); | |
} | |
/** | |
* @param e | |
* @return | |
* @see java.util.List#add(java.lang.Object) | |
*/ | |
public boolean add(String e) { | |
return list.add(e); | |
} | |
/** | |
* @param id | |
*/ | |
public DataObject(String id) { | |
super(); | |
this.id = id; | |
} | |
public DataObject() { | |
super(); | |
} | |
/** | |
* @return id | |
*/ | |
public String getId() { | |
return id; | |
} | |
/** | |
* @param id | |
* セットする id | |
*/ | |
public void setId(String id) { | |
this.id = id; | |
} | |
/* (非 Javadoc) | |
* @see java.lang.Object#toString() | |
*/ | |
@Override | |
public String toString() { | |
StringBuilder builder = new StringBuilder(); | |
builder.append("DataObject [id="); | |
builder.append(id); | |
builder.append("]"); | |
builder.append(" Size" + list.size()); | |
builder.append(Arrays.toString(list.toArray())); | |
return builder.toString(); | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.sample.koozz; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.Collections; | |
import java.util.Iterator; | |
import java.util.List; | |
import java.util.UUID; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.util.StopWatch; | |
public class Client { | |
/** ロガー */ | |
private static final Logger logger = LoggerFactory.getLogger(Client.class); | |
public static void main(String[] args) { | |
StopWatch stopWatch = new StopWatch(UUID.randomUUID().toString()); | |
stopWatch.start(); | |
Arrarys arrarys = new Arrarys(); | |
DataObject[] dtos = new DataObject[] { new DataObject(UUID.randomUUID().toString()), | |
new DataObject(UUID.randomUUID().toString()), | |
new DataObject(UUID.randomUUID().toString()) }; | |
arrarys.addAllToDeepCopy(dtos); | |
arrarys.console(); | |
logger.info("以下、インスタンスの使い回し"); | |
for (int i = 0; i < dtos.length; i++) { | |
dtos[i].setId(UUID.randomUUID().toString()); | |
dtos[i].add(dtos[i].getId()); | |
} | |
arrarys.addAllToDeepCopy(dtos); | |
arrarys.console(); | |
logger.info("-----------------------------"); | |
for (int i = 0; i < dtos.length; i++) { | |
dtos[i].setId(UUID.randomUUID().toString()); | |
dtos[i].add(dtos[i].getId()); | |
} | |
arrarys.addAllToDeepCopy(dtos); | |
// DeepCopyであることを証明するためにリストをクリアする。 | |
for (DataObject dataObject : dtos) { | |
dataObject.clear(); | |
} | |
arrarys.console(); | |
logger.info("-----------------------------"); | |
stopWatch.stop(); | |
logger.info("処理時間 {}{}", stopWatch.getTotalTimeMillis(),"ms"); | |
} | |
private static class Arrarys { | |
// リストの同期化 | |
List<DataObject> list = Collections.synchronizedList(new ArrayList<DataObject>()); | |
/** | |
* 受け取った{@code dtos}を{@code list}に追加する際に{@code DataObject}を新規追加し、 | |
* 値を移し替えることでディープコピーを実現する。 | |
* @param dtos {@code list}に追加する{@code DateObject} | |
*/ | |
public void addAllToDeepCopy(DataObject... dtos) { | |
synchronized (list) { | |
DataObject[] deepCopy = new DataObject[dtos.length]; | |
for (int i = 0; i < deepCopy.length; i++) { | |
deepCopy[i] = new DataObject(dtos[i].getId()); | |
deepCopy[i].addAll(dtos[i].getList()); | |
// try { | |
// deepCopy[i] = (DataObject)BeanUtils.cloneBean(dtos[i]); | |
// deepCopy[i].addAll(dtos[i].getList()); | |
// // shallwCopy | |
// // Collections.copy(dtos[i].getList(), deepCopy[i].getList()); | |
// } | |
// catch (IllegalAccessException e) { | |
// e.printStackTrace(); | |
// } | |
// catch (InstantiationException e) { | |
// e.printStackTrace(); | |
// } | |
// catch (InvocationTargetException e) { | |
// e.printStackTrace(); | |
// } | |
// catch (NoSuchMethodException e) { | |
// e.printStackTrace(); | |
// } | |
} | |
list.addAll(Arrays.asList(deepCopy)); | |
} | |
} | |
@SuppressWarnings("unused") | |
public void addAllToShallwCopy(DataObject... dtos) { | |
synchronized (list) { | |
DataObject[] shallwCopy = new DataObject[dtos.length]; | |
System.arraycopy(dtos, 0, shallwCopy, 0, shallwCopy.length); | |
list.addAll(Arrays.asList(shallwCopy)); | |
} | |
} | |
public void console() { | |
synchronized (list) { | |
Iterator<DataObject> iterator = list.iterator(); | |
while (iterator.hasNext()) { | |
DataObject dto = (DataObject) iterator.next(); | |
logger.info(dto.toString()); | |
} | |
} | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment