大家,好!本人菜鸟,闲时,偶看重构,发现非常非常有帮助,但是先在在实际编程中遇到了个问题,不知道如何是“好”,特此求助!
问题表述:当用list做为参数时(可能有些狭隘,容器),如何在不改变list原来地址的内容而修改list,是否有一种克隆list的写法?用iterator?这地方我搞得就不太清楚。我要确保的一个原则是,方法的参数是用来看的,而不是用来改的。
希望大家发散思维,随便说说,就当交流了!
我也向各位老师好好学学!!!
问题表述:当用list做为参数时(可能有些狭隘,容器),如何在不改变list原来地址的内容而修改list,是否有一种克隆list的写法?用iterator?这地方我搞得就不太清楚。我要确保的一个原则是,方法的参数是用来看的,而不是用来改的。
希望大家发散思维,随便说说,就当交流了!
我也向各位老师好好学学!!!
也就是说
List list = new ArrayList();change(List list) {
list = new ArrayList(); //这里的改变是不影响上面的list的指向的
}如果LZ的意思是list(容器)里的对象是不允许改变的,那么可以使用
Collections.unmodifiableList(List<? extends T> list)即调用方法时
change(Collections.unmodifiableList(list));
foo里需要list的数据,并且随着方法的进行,需要对计算出来的数据临时保存到list(进行修改)但是,退出foo后又不能让foo中的修改更新到l1中简单的说,就是需要在foo中声明一个临时变量,它的内容和l1一模一样LZ俺说的对不 = =
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;public class A {
public void foo(Collection<?> list) {
ArrayList<Object> tmp = new ArrayList<Object>(list); for (int i = 0; i < tmp.size(); i++) {
System.out.println(tmp.get(i));
} if (tmp.contains("Hello")) {
tmp.add("haha");
} for (int i = 0; i < tmp.size(); i++) {
System.out.println(tmp.get(i));
}
} public static void main(String args[]) {
A a = new A(); List<String> list = new ArrayList<String>();
list.add("Hello");
list.add("World!"); a.foo(list); for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
} }
}
这时如果在方法里操作了inlist地址的内容,那么就等于把外部的exlist的内容也改变了。如果只是为了一些查询之类的才调用方法,那不必担心啊。
如果想同样修改一个list指向内容,而不破坏原来的,那复制一个不就行了。这时调用方法就传刚复制的那个地址。
ByteArrayOutputStream bo=new ByteArrayOutputStream();
ObjectOutputStream oo=new ObjectOutputStream(bo);
oo.writeObject(obj);
ByteArrayInputStream bi=new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi=new ObjectInputStream(bi);
Object result = oi.readObject() ;
bo.close() ;
oo.close() ;
bi.close() ;
oi.close() ;
return result;
}
@SuppressWarnings("unchecked")
public static List<?> deepCloneList(Iterator<?> pIterator) throws IOException, ClassNotFoundException{
List result = new ArrayList() ;
while(pIterator.hasNext()){
result.add(deepClone( pIterator.next())) ;
}
return result;
}
另外,如果哪位老师觉得我的做法古怪或者不标准,哪怕是不好,非常可请您指出!!!
或者是哪位老师认为就不应该克隆,请您指导!!!
你的形容很贴切 脱裤子放*1 首先你觉得在void方法中修改是猥琐的
- 我没觉得猥琐 = = 如果你还是觉得猥琐,那么你可以修改完之后,将它返回,就可以不猥琐了2 很容易让维护人员迷惑
- 清晰的注释、文档、方法名称、参数/变量名称都可以有效减少维护人员阅读代码的难度。
比起直接修改,我反倒觉得你这样的做法更让人迷惑,克隆神马的不符合人的直观思维。
3
- 我就不提克隆所作的额外工作对于整个项目的影响了。
我猥琐...
其实,在重构里的要求是这样的,和大家分享一下,“可以修改参数对象的内部状态,但对参数对象重新赋值没有意义。”
是我理解的太狭隘了,原话的意思应该是说,如果是引用数据类型的话,那么对其使用setter和getter方法是没问题的,但是如果是对象的重新赋值,就不ok了!
也就是说,可以将参数全都设成是final的(当然,只要知道有这回事儿就好,过于短的函数没有必要设置成final的,函数如果过长的话还是可以起到辅助编程的作用。)。
结贴!
感谢11楼得一如既往!