Java 8流,lambda(Java 8 streams, lambdas)

系统教程 行业动态 更新时间:2024-06-14 16:59:17
Java 8流,lambda(Java 8 streams, lambdas)

我试图学习如何在我的日常编程中使用Java 8功能(如lambdas和流),因为它使代码更简洁。

以下是我目前正在处理的内容:我从本地文件中获取字符串流,其中包含一些数据,稍后将转为对象。 输入文件结构看起来像这样:

Airport name; Country; Continent; some number;

我的代码如下所示:

public class AirportConsumer implements AirportAPI { List<Airport> airports = new ArrayList<Airport>(); @Override public Stream<Airport> getAirports() { Stream<String> stream = null; try { stream = Files.lines(Paths.get("resources/planes.txt")); stream.forEach(line -> createAirport(line)); } catch (IOException e) { e.printStackTrace(); } return airports.stream(); } public void createAirport(String line) { String airport, country, continent; int length; airport = line.substring(0, line.indexOf(';')).trim(); line = line.replace(airport + ";", ""); country = line.substring(0,line.indexOf(';')).trim(); line = line.replace(country + ";", ""); continent = line.substring(0,line.indexOf(';')).trim(); line = line.replace(continent + ";", ""); length = Integer.parseInt(line.substring(0,line.indexOf(';')).trim()); airports.add(new Airport(airport, country, continent, length)); } }

在我的主类中,我遍历对象流并打印出结果:

public class Main { public void toString(Airport t){ System.out.println(t.getName() + " " + t.getContinent()); } public static void main(String[] args) throws IOException { Main m = new Main(); m.whatever(); } private void whatever() throws IOException { AirportAPI k = new AirportConsumer(); Stream<Airport> s; s = k.getAirports(); s.forEach(this::toString); } }

我的问题是:我怎样才能优化这段代码,所以我不必分别解析文件中的行,而是从源文件中直接创建一个对象流? 或者这是我能做到这一点的程度?

I am trying to learn how to utilize Java 8 features(such as lambdas and streams) in my daily programming, since it makes for much cleaner code.

Here's what I am currently working on: I get a string stream from a local file with some data which I turn into objects later. The input file structure looks something like this:

Airport name; Country; Continent; some number;

And my code looks like this:

public class AirportConsumer implements AirportAPI { List<Airport> airports = new ArrayList<Airport>(); @Override public Stream<Airport> getAirports() { Stream<String> stream = null; try { stream = Files.lines(Paths.get("resources/planes.txt")); stream.forEach(line -> createAirport(line)); } catch (IOException e) { e.printStackTrace(); } return airports.stream(); } public void createAirport(String line) { String airport, country, continent; int length; airport = line.substring(0, line.indexOf(';')).trim(); line = line.replace(airport + ";", ""); country = line.substring(0,line.indexOf(';')).trim(); line = line.replace(country + ";", ""); continent = line.substring(0,line.indexOf(';')).trim(); line = line.replace(continent + ";", ""); length = Integer.parseInt(line.substring(0,line.indexOf(';')).trim()); airports.add(new Airport(airport, country, continent, length)); } }

And in my main class I iterate over the object stream and print out the results:

public class Main { public void toString(Airport t){ System.out.println(t.getName() + " " + t.getContinent()); } public static void main(String[] args) throws IOException { Main m = new Main(); m.whatever(); } private void whatever() throws IOException { AirportAPI k = new AirportConsumer(); Stream<Airport> s; s = k.getAirports(); s.forEach(this::toString); } }

My question is this: How can I optimize this code, so I don't have to parse the lines from the file separately, but instead create a stream of objects Airport straight from the source file? Or is this the extent in which I can do this?

最满意答案

您需要使用map()来转换过去的数据。

Files.lines(Paths.get("resources/planes.txt")) .map(line -> createAirport(line));

这将返回一个Stream<Airport> - 如果你想返回一个List ,那么你需要在最后使用collect方法。

这种方法也是无状态的,这意味着您不需要实例级别的airports值。

您需要更新您的createAirport方法才能返回某些内容:

public Airport createAirport(String line) { String airport = line.substring(0, line.indexOf(';')).trim(); line = line.replace(airport + ";", ""); String country = line.substring(0,line.indexOf(';')).trim(); line = line.replace(country + ";", ""); String continent = line.substring(0,line.indexOf(';')).trim(); line = line.replace(continent + ";", ""); int length = Integer.parseInt(line.substring(0,line.indexOf(';')).trim()); return new Airport(airport, country, continent, length); }

如果您正在寻找更加实用的代码方法,您可能需要考虑重写createAirport以免它改变行。 建筑商对这种事情也很好。

public Airport createAirport(final String line) { final String[] fields = line.split(";"); return new Airport(fields[0].trim(), fields[1].trim(), fields[2].trim(), Integer.parseInt(fields[3].trim())); }

把它们放在一起,你的班级现在看起来像这样。

public class AirportConsumer implements AirportAPI { @Override public Stream<Airport> getAirports() { Stream<String> stream = null; try { stream = Files.lines(Paths.get("resources/planes.txt")) .map(line -> createAirport(line)); } catch (IOException e) { stream = Stream.empty(); e.printStackTrace(); } return stream; } private Airport createAirport(final String line) { final String[] fields = line.split(";"); return new Airport(fields[0].trim(), fields[1].trim(), fields[2].trim(), Integer.parseInt(fields[3].trim())); } }

You need to use map() to transform the data as it comes past.

Files.lines(Paths.get("resources/planes.txt")) .map(line -> createAirport(line));

This will return a Stream<Airport> - if you want to return a List, then you'll need to use the collect method at the end.

This approach is also stateless, which means you won't need the instance-level airports value.

You'll need to update your createAirport method to return something:

public Airport createAirport(String line) { String airport = line.substring(0, line.indexOf(';')).trim(); line = line.replace(airport + ";", ""); String country = line.substring(0,line.indexOf(';')).trim(); line = line.replace(country + ";", ""); String continent = line.substring(0,line.indexOf(';')).trim(); line = line.replace(continent + ";", ""); int length = Integer.parseInt(line.substring(0,line.indexOf(';')).trim()); return new Airport(airport, country, continent, length); }

If you're looking for a more functional approach to your code, you may want to consider a rewrite of createAirport so it doesn't mutate line. Builders are also nice for this kind of thing.

public Airport createAirport(final String line) { final String[] fields = line.split(";"); return new Airport(fields[0].trim(), fields[1].trim(), fields[2].trim(), Integer.parseInt(fields[3].trim())); }

Throwing it all together, your class now looks like this.

public class AirportConsumer implements AirportAPI { @Override public Stream<Airport> getAirports() { Stream<String> stream = null; try { stream = Files.lines(Paths.get("resources/planes.txt")) .map(line -> createAirport(line)); } catch (IOException e) { stream = Stream.empty(); e.printStackTrace(); } return stream; } private Airport createAirport(final String line) { final String[] fields = line.split(";"); return new Airport(fields[0].trim(), fields[1].trim(), fields[2].trim(), Integer.parseInt(fields[3].trim())); } }

更多推荐

本文发布于:2023-04-16 14:39:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/dzcp/e8128ca0ea1764b45b9ced6105a76a30.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:lambda   Java   lambdas   streams

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!