如何从 ArrayList 中提取特定数字?
How to extract specific number from a ArrayList?
我编写了一个程序,它将从 http://worldtimeapi.org/api/ip.txt 获取文本数据,并提取 X,其中 X 是 "unixtime" 旁边的值。这是我到目前为止得到的。
public class GetDataService implements DataService{
@Override
public ArrayList<String> getData() {
ArrayList<String> lines = new ArrayList<>();
try {
URL url = new URL("http://worldtimeapi.org/api/ip.txt");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
String a = line;
lines.add(a);
}
bufferedReader.close();
} catch (IOException ex) {
throw new RuntimeException("Can not making the request to the URL.");
}
return lines;
}
public interface DataService {
ArrayList<String> getData() throws IOException;
}
public class UnixTimeExtractor {
private GetDataService getDataService;
public String unixTimeExtractor() {
ArrayList<String> lines = getDataService.getData();
//how to extract the value next to "unixtime"
我不知道如何提取 "unixtime" 旁边的值。以及如何测试 GetDataService Class.
的网络错误
您可以使用 indexOf
遍历 ArrayList 并获取下一个值
public String unixTimeExtractor() {
List<String> lines = getDataService.getData();
int i = lines.indexOf(unixTime);
if (i != -1 && ++i < lines.size()) {
return lines.get(i);
}
return null;
}
I don't know how to extract value next to "unixtime".
要从列表中提取值,您可以遍历列表,
根据需要对每个值进行一些检查,
和 return 找到匹配项时的值,例如:
for (String line : lines) {
if (line.startsWith("unixtime: ")) {
return line;
}
}
要提取字符串中 "unixtime: " 之后的值,您可以使用多种策略:
line.substring("unixtime: ".length())
line.replaceAll("^unixtime: ", "")
line.split(": ")[1]
- ...
顺便说一句,你真的需要行列表吗?
如果不是,那么如果您在从 URL 读取输入流时执行此检查,则可以节省内存并减少输入处理,
找到所需内容后立即停止阅读。
And how can I test NetWork Error for GetDataService Class.
要测试是否正确处理了网络错误,
您需要使可能引发网络错误的代码部分可注入。
然后在您的测试用例中,您可以注入将抛出异常的替换代码,
并验证程序是否正确处理异常。
一种技术是"extract and extend"。
即,提取对专用方法的 url.openStream()
调用:
InputStream getInputStream(URL url) throws IOException {
return url.openStream();
}
并将您的代码 url.openStream()
替换为对 getInputStream(url)
的调用。
然后在你的测试方法中,你可以通过抛出异常来覆盖这个方法,
并验证会发生什么。在 AssertJ 中使用流畅的断言:
@Test
public void test_unixtime() {
UnixTimeExtractor extractor = new UnixTimeExtractor() {
@Override
InputStream getInputStream(URL url) throws IOException {
throw new IOException();
}
};
assertThatThrownBy(extractor::unixtime)
.isInstanceOf(RuntimeException.class)
.hasMessage("Error while reading from stream");
}
您可以对输入流进行类似的读取。
您可以使用 java-8 来实现同样的效果。将您的方法更改为以下内容:
public String unixTimeExtractor() {
ArrayList<String> lines = getDataService.getData();
return lines.stream().filter(s -> s.contains("unixtime"))
.map(s -> s.substring("unixtime: ".length()))
.findFirst()
.orElse("Not found");
}
此处我们流式传输列表 lines
以检查是否找到 String unixtime
。如果找到,那么我们 return 使用子字符串的值,否则我们 return Not found
.
测试用例可以参考janos的回答
我编写了一个程序,它将从 http://worldtimeapi.org/api/ip.txt 获取文本数据,并提取 X,其中 X 是 "unixtime" 旁边的值。这是我到目前为止得到的。
public class GetDataService implements DataService{
@Override
public ArrayList<String> getData() {
ArrayList<String> lines = new ArrayList<>();
try {
URL url = new URL("http://worldtimeapi.org/api/ip.txt");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
String a = line;
lines.add(a);
}
bufferedReader.close();
} catch (IOException ex) {
throw new RuntimeException("Can not making the request to the URL.");
}
return lines;
}
public interface DataService {
ArrayList<String> getData() throws IOException;
}
public class UnixTimeExtractor {
private GetDataService getDataService;
public String unixTimeExtractor() {
ArrayList<String> lines = getDataService.getData();
//how to extract the value next to "unixtime"
我不知道如何提取 "unixtime" 旁边的值。以及如何测试 GetDataService Class.
的网络错误您可以使用 indexOf
遍历 ArrayList 并获取下一个值
public String unixTimeExtractor() {
List<String> lines = getDataService.getData();
int i = lines.indexOf(unixTime);
if (i != -1 && ++i < lines.size()) {
return lines.get(i);
}
return null;
}
I don't know how to extract value next to "unixtime".
要从列表中提取值,您可以遍历列表, 根据需要对每个值进行一些检查, 和 return 找到匹配项时的值,例如:
for (String line : lines) {
if (line.startsWith("unixtime: ")) {
return line;
}
}
要提取字符串中 "unixtime: " 之后的值,您可以使用多种策略:
line.substring("unixtime: ".length())
line.replaceAll("^unixtime: ", "")
line.split(": ")[1]
- ...
顺便说一句,你真的需要行列表吗? 如果不是,那么如果您在从 URL 读取输入流时执行此检查,则可以节省内存并减少输入处理, 找到所需内容后立即停止阅读。
And how can I test NetWork Error for GetDataService Class.
要测试是否正确处理了网络错误, 您需要使可能引发网络错误的代码部分可注入。 然后在您的测试用例中,您可以注入将抛出异常的替换代码, 并验证程序是否正确处理异常。
一种技术是"extract and extend"。
即,提取对专用方法的 url.openStream()
调用:
InputStream getInputStream(URL url) throws IOException {
return url.openStream();
}
并将您的代码 url.openStream()
替换为对 getInputStream(url)
的调用。
然后在你的测试方法中,你可以通过抛出异常来覆盖这个方法,
并验证会发生什么。在 AssertJ 中使用流畅的断言:
@Test
public void test_unixtime() {
UnixTimeExtractor extractor = new UnixTimeExtractor() {
@Override
InputStream getInputStream(URL url) throws IOException {
throw new IOException();
}
};
assertThatThrownBy(extractor::unixtime)
.isInstanceOf(RuntimeException.class)
.hasMessage("Error while reading from stream");
}
您可以对输入流进行类似的读取。
您可以使用 java-8 来实现同样的效果。将您的方法更改为以下内容:
public String unixTimeExtractor() {
ArrayList<String> lines = getDataService.getData();
return lines.stream().filter(s -> s.contains("unixtime"))
.map(s -> s.substring("unixtime: ".length()))
.findFirst()
.orElse("Not found");
}
此处我们流式传输列表 lines
以检查是否找到 String unixtime
。如果找到,那么我们 return 使用子字符串的值,否则我们 return Not found
.
测试用例可以参考janos的回答