Skip to content

Instantly share code, notes, and snippets.

@openbooks
Last active August 30, 2015 04:20
Show Gist options
  • Save openbooks/11553177 to your computer and use it in GitHub Desktop.
Save openbooks/11553177 to your computer and use it in GitHub Desktop.
配列のShallwCopyとDeepCopyの実現方法 ref: http://qiita.com/Koo_zZ/items/269105e59e158ea9732d
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, アオレンジャー, キレンジャー, ピンクレンジャー, ミドレンジャー]コピー先
}
}
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();
}
}
}
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();
}
}
}
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, アオレンジャー, キレンジャー, ピンクレンジャー, ミドレンジャー]コピー先
}
}
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();
}
}
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