一开始:我没有找到任何可能对互联网资源有帮助的信息。
在需要序列化支持时尝试将迭代对象转换为新对象时,我确实遇到了一些问题。 基本上我们假设应用程序中的一些复杂过程 AP1 为您提供了一个 Iterable 接口,用于某些大型集合对象,即 BaseClass 类型。从这些对象接收的部分数据应在另一个应用程序 AP2 中用作新对象,即 TargetClass 类型。这两个对象之间的转换 BaseClass-> TargetClass 非常复杂,需要在将对象发送到目标应用程序之前执行。 任何想法如何实现?
下面的一些简化示例介绍了该问题。代码是可运行的。一个测试" testForTargetDataSource_with_Serialization()" 4个测试用例失败,原因是" java.lang.ClassCastException:IterableTest $ TargetDataSource $ 1无法强制转换为java.io.Serializable "。
此异常的原因非常明显,而在 next()方法中,我使用大量不同的对象进行转换,这些对象不是可序列化的(您可以参考< em> public TargetClass next() - 在实例中,这非常复杂。)。
public TargetClass next() {
BaseClass bcObj = dsIterator.next();
return new TargetClass(bcObj.getFirstName(), bcObj.getSecondName());
}
TargetDataSource 的 hasNext()方法也存在同样的问题。
实施例
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang3.SerializationUtils;
import org.junit.Test;
public class IterableTest implements Serializable {
@Test
public void testForStandardDataSource() {
DataSource ds = new DataSource();
Iterator<BaseClass> iterator = ds.getData().iterator();
assertEquals("B", iterator.next().getSecondName());
assertEquals("C", iterator.next().getSecondName());
assertEquals("D", iterator.next().getSecondName());
}
@Test
public void testForTargetDataSource() {
TargetDataSource tdc = new TargetDataSource();
Iterator<TargetClass> iter = tdc.getData().iterator();
while (iter.hasNext()) {
System.out.println(iter.next().getFullName());
}
}
@Test
public void testForStandardDataSource_with_Serialization() {
DataSource ds = new DataSource();
Iterable<BaseClass> iter = ds.getData();
byte[] bytes = SerializationUtils.serialize((Serializable) iter);
@SuppressWarnings("unchecked")
Iterable<BaseClass> iter2 = (Iterable<BaseClass>) SerializationUtils.deserialize(bytes);
assertNotSame(iter, iter2);
Iterator<BaseClass> iterator = iter2.iterator();
assertEquals("B", iterator.next().getSecondName());
assertEquals("C", iterator.next().getSecondName());
assertEquals("D", iterator.next().getSecondName());
}
@Test
public void testForTargetDataSource_with_Serialization() {
TargetDataSource tdc = new TargetDataSource();
Iterable<TargetClass> iter = tdc.getData();
byte[] bytes = SerializationUtils.serialize((Serializable) iter);
@SuppressWarnings("unchecked")
Iterable<TargetClass> iter2 = (Iterable<TargetClass>) SerializationUtils.deserialize(bytes);
assertNotSame(iter, iter2);
Iterator<TargetClass> iterator = iter2.iterator();
assertEquals("A B", iterator.next().getFullName());
assertEquals("A C", iterator.next().getFullName());
assertEquals("A D", iterator.next().getFullName());
}
class BaseClass implements Serializable {
private String firstName;
private String secondName;
public BaseClass(String firstName, String secondName) {
super();
this.firstName = firstName;
this.secondName = secondName;
}
String getFirstName() {
return firstName;
}
String getSecondName() {
return secondName;
}
}
class TargetClass implements Serializable {
private String fullName;
public TargetClass() {
}
public TargetClass(String firstName, String lastName) {
super();
this.fullName = firstName + " " + lastName;
}
public String getFullName() {
return fullName;
}
}
class DataSource {
private final List<BaseClass> data = Arrays.asList(new BaseClass("A", "B"), new BaseClass("A", "C"),
new BaseClass("A", "D"));
public Iterable<BaseClass> getData() {
return data;
}
}
class TargetDataSource {
final DataSource ds = new DataSource();
Iterator<BaseClass> dsIterator = ds.getData().iterator();
public Iterable<TargetClass> getData() {
return new Iterable<TargetClass>() {
public Iterator<TargetClass> iterator() {
return new Iterator<TargetClass>() {
public boolean hasNext() {
return dsIterator.hasNext();
}
public TargetClass next() {
BaseClass bcObj = dsIterator.next();
return new TargetClass(bcObj.getFirstName(), bcObj.getSecondName());
}
public void remove() {
// do nothing
}
};
}
};
}
}
}