我正在为学校解决问题。很多这种方法已经实施,我不允许做太多改动。
实际上我只能在特定点进行更改。
这里是我正在研究的方法的代码,虽然有些单词是荷兰语,但它应该是可读的。
它应该读取文件的行,从文本创建地址(保存为(街道+"" +数字+"" +地点))并添加它们到返回的列表。该文件以空行结束。
@Override
public List<Adres> query(ISpecification specification) {
if (specification instanceof FileSpecification) {
if (((FileSpecification) specification).toFileQuery().equals("ALL")) {
ArrayList<Adres> adressen = new ArrayList<>();
/*---start of my code*/
File studentF = new File(fsConnection.getStudentConnection());
try {
FileReader fr = new FileReader(studentF);
BufferedReader br = new BufferedReader(fr);
br.lines().forEach(new Consumer<String>(){
@Override
public void accept(String line) {
String[] words = line.split("\\s");
if(words.length == 3){
/*line i'm having trouble with*/adressen.add(new Adres(words[0], Integer.parseInt(words[1]), words[2]);
}
}
});
} catch (FileNotFoundException ex) {
Logger.getLogger(AdresFile.class.getName()).log(Level.SEVERE, null, ex);//Don't mind this
}
/*---end of my code*/
//System.out.println("query: Nog niet geimplementeerd!");
return adressen;
} else {
return null;
}
} else {
return null;
}
}
如您所见,我想访问消费者块之外的列表。我知道现在这是不可能的。我想过创建一个不同的方法,但这是不允许的。我必须使用foreach方法。任何帮助表示赞赏。
答案 0 :(得分:2)
当您使用Java7时,编译器需要
final ArrayList<Adres> adressen = new ArrayList<>();
那里。关键是:你想在中使用那个局部变量一个非常内在的类;换句话说:在一个与您放置源代码的类以某种方式分离的上下文中。并且为了使解耦类能够使用,adressen需要是最终的(以便编译器知道:该引用稍后不会更改)。并且鉴于你的评论:不,这并没有神奇地将一个对象变成不可变的。它只是阻止引用更改它指向的“目标”!
但由于你不允许改变这一行,你可以选择:
ArrayList<Adres> adressen = new ArrayList<>();
final ArrayList<Adres> tempAdressen = adressen;
然后您的代码使用tempAdressen。
或者,我假设您使用的是Java7。使用Java8,编译器应该能够理解adressen
是有效的最终;因此它应该按原样接受源代码。
答案 1 :(得分:0)
由于在BufferedReader中调用lines()
,您似乎已经在使用Java8。
所以我的建议是做一张地图然后收集列表,而不是forEach。这样您就不需要从消费者中访问该列表。
adressen.addAll(
br.lines().map(line -> {
String[] words = line.split("\\s");
if (words.length == 3) {
return new Adres(words[0], Integer.parseInt(words[1]), words[2]);
}
return null;
})
.filter(Objects::nonNull)
.collect(Collectors.toList())
);
答案 2 :(得分:0)
使用Java8,您可以使用 java.util.stream.Collectors 直接从流中返回元素列表。使用收集器可以帮助您避免副作用(在您的情况下,需要使用外部数组来解析元素)。
我会亲自使用以下lambda编写它:
List<Adres> adressen = br.lines().stream()
.map(line -> line.split("\\s"))
.filter(words -> words.length == 3)
.map(words -> new Adres(words[0], Integer.parseInt(words[1]), words[2]))
.collect(Collectors.toList());
这将有效,但它不会处理数据格式错误的情况。要解决这个问题,可以通过修改lambda(即使这不是很优雅)来改变上面的代码来处理一行是否由3个元素组成:
List<Adres> adressen = br.lines().stream()
.map(line -> line.split("\\s"))
.filter(words -> {
if (words.length == 3)
return true;
else {
throw new IllegalArgumentException();
}
})
.map(words -> new Adres(words[0], Integer.parseInt(words[1]), words[2]))
.collect(Collectors.toList());