Completable Future - 使用 Completable Future 我正在尝试来自两个不同文件的数据
Completable Future - Using Completable Future I am trying to the data from two different files
我正在尝试从两个不同的文件中读取数据,一个是 csv 格式,另一个文件来自 xml data.using completeFuture 我正在尝试从两个异步文件中读取数据。我收到类型转换错误。
请让我知道我是否按照正确的方法在下面的代码中使用 completefuture 对象
异常:
java.lang.ClassCastException: class java.util.ArrayList cannot be cast to class java.util.function.Supplier (java.util.ArrayList and java.util.function.Supplier are in module java.base of loader 'bootstrap')
从主线程读取数据的代码
CompletableFuture<Object> csvdata = CompletableFuture.supplyAsync((Supplier<Object>) processdatacsv());
CompletableFuture<Object> xmldata1 = CompletableFuture.supplyAsync((Supplier<Object>) processxmldata());
List<String[]> csvfiledata = null;
if (csvdata.isDone())
csvfiledata = (List<String[]>) csvdata.get();
List<String[]> xmlfiledata = null;
if (xmldata1.isDone())
xmlfiledata = (List<String[]>) xmldata1.get();
private List<String[]> processdatacsv() {
CSVReader reader = null;
Resource resource1 = new ClassPathResource("sample.csv");
try {
String csvFile = resource1.getFile().toString();
reader = new CSVReader(new FileReader(csvFile));
return reader.readAll();
} catch (Exception e) {
LOGGER.error("Error while process csv records");
return null;
}
}
private List<String[]> processxmldata() {
Resource resource = new ClassPathResource("sample.xml");
File file;
try {
file = resource.getFile();
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder;
dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(file);
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getElementsByTagName("record");
System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
List<String[]> dataList = new ArrayList<String[]>();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) node;
String[] data = new String[3];
data[0] = eElement.getAttribute("reference").toString();
data[1] = eElement.getElementsByTagName("Number").item(0).getTextContent().toString();
data[2] = eElement.getElementsByTagName("des").item(0).getTextContent().toString();
}
}
return dataList;
} catch (Exception e) {
LOGGER.error("Error while process csv records");
return null;
}
}
如异常所述:您不能只将列表转换为供应商对象。一个 Supplier is an object that has a get 方法来请求它提供的对象(在你的情况下是一个列表)。
在你的代码中,文件不会被异步加载,因为你直接调用方法 processdatacsv
和 processxmldata
,所以它们会被直接执行。要稍后(在另一个线程中)执行这些方法,您需要 Supplier(以便另一个线程可以调用 get 方法并执行代码)。
在您在问题中提供的代码中,使用 lambda expressions 最简单:
CompletableFuture<List<String[]>> csvdata = CompletableFuture.supplyAsync(() -> processdatacsv());
CompletableFuture<List<String[]>> xmldata1 = CompletableFuture.supplyAsync(() -> processxmldata());
在此代码片段中,() -> processdatacsv()
部分可以解释为:创建一个新的 Supplier 对象,该对象从其方法 get
.
调用方法 processdatacsv
或者你可以这样做(可能更容易理解):
CompletableFuture<List<String[]>> csvdata = CompletableFuture.supplyAsync(new Supplier<List<String[]>>() {
public List<String[]> get() {
processdatacsv();
}
});
CompletableFuture<List<String[]>> csvdata = CompletableFuture.supplyAsync(new Supplier<List<String[]>>() {
public List<String[]> get() {
processxmldata();
}
});
对于 CompletableFuture.supplyAsync
你需要一个 Supplier
。这不能通过将列表转换为 Supplier<Object>
类型来完成。正确的方法是这样的:
CompletableFuture<List<String[]>> xmldata1 = CompletableFuture.supplyAsync(() -> processxmldata());
使用 Supplier
的原因是求值不能立即从构造 Supplier
的语句开始。 Future
将在异步线程中开始计算。
以后真的要结果的话,就等着吧。最简单的方法就是:
xmlfiledata = xmldata1.get();
看看 get 方法的 javadoc。
我正在尝试从两个不同的文件中读取数据,一个是 csv 格式,另一个文件来自 xml data.using completeFuture 我正在尝试从两个异步文件中读取数据。我收到类型转换错误。 请让我知道我是否按照正确的方法在下面的代码中使用 completefuture 对象
异常:
java.lang.ClassCastException: class java.util.ArrayList cannot be cast to class java.util.function.Supplier (java.util.ArrayList and java.util.function.Supplier are in module java.base of loader 'bootstrap')
从主线程读取数据的代码
CompletableFuture<Object> csvdata = CompletableFuture.supplyAsync((Supplier<Object>) processdatacsv());
CompletableFuture<Object> xmldata1 = CompletableFuture.supplyAsync((Supplier<Object>) processxmldata());
List<String[]> csvfiledata = null;
if (csvdata.isDone())
csvfiledata = (List<String[]>) csvdata.get();
List<String[]> xmlfiledata = null;
if (xmldata1.isDone())
xmlfiledata = (List<String[]>) xmldata1.get();
private List<String[]> processdatacsv() {
CSVReader reader = null;
Resource resource1 = new ClassPathResource("sample.csv");
try {
String csvFile = resource1.getFile().toString();
reader = new CSVReader(new FileReader(csvFile));
return reader.readAll();
} catch (Exception e) {
LOGGER.error("Error while process csv records");
return null;
}
}
private List<String[]> processxmldata() {
Resource resource = new ClassPathResource("sample.xml");
File file;
try {
file = resource.getFile();
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder;
dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(file);
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getElementsByTagName("record");
System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
List<String[]> dataList = new ArrayList<String[]>();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) node;
String[] data = new String[3];
data[0] = eElement.getAttribute("reference").toString();
data[1] = eElement.getElementsByTagName("Number").item(0).getTextContent().toString();
data[2] = eElement.getElementsByTagName("des").item(0).getTextContent().toString();
}
}
return dataList;
} catch (Exception e) {
LOGGER.error("Error while process csv records");
return null;
}
}
如异常所述:您不能只将列表转换为供应商对象。一个 Supplier is an object that has a get 方法来请求它提供的对象(在你的情况下是一个列表)。
在你的代码中,文件不会被异步加载,因为你直接调用方法 processdatacsv
和 processxmldata
,所以它们会被直接执行。要稍后(在另一个线程中)执行这些方法,您需要 Supplier(以便另一个线程可以调用 get 方法并执行代码)。
在您在问题中提供的代码中,使用 lambda expressions 最简单:
CompletableFuture<List<String[]>> csvdata = CompletableFuture.supplyAsync(() -> processdatacsv());
CompletableFuture<List<String[]>> xmldata1 = CompletableFuture.supplyAsync(() -> processxmldata());
在此代码片段中,() -> processdatacsv()
部分可以解释为:创建一个新的 Supplier 对象,该对象从其方法 get
.
processdatacsv
或者你可以这样做(可能更容易理解):
CompletableFuture<List<String[]>> csvdata = CompletableFuture.supplyAsync(new Supplier<List<String[]>>() {
public List<String[]> get() {
processdatacsv();
}
});
CompletableFuture<List<String[]>> csvdata = CompletableFuture.supplyAsync(new Supplier<List<String[]>>() {
public List<String[]> get() {
processxmldata();
}
});
对于 CompletableFuture.supplyAsync
你需要一个 Supplier
。这不能通过将列表转换为 Supplier<Object>
类型来完成。正确的方法是这样的:
CompletableFuture<List<String[]>> xmldata1 = CompletableFuture.supplyAsync(() -> processxmldata());
使用 Supplier
的原因是求值不能立即从构造 Supplier
的语句开始。 Future
将在异步线程中开始计算。
以后真的要结果的话,就等着吧。最简单的方法就是:
xmlfiledata = xmldata1.get();
看看 get 方法的 javadoc。