Java 将Files.lines与.map一起使用(line->;line.split(";多个分隔符";)
我有一个输入文件,格式如下: 安大略省:布兰顿:北纬43度41度79度45度西 安大略省:多伦多:43°39'北纬:79°23'西 魁北克:蒙特利尔:北纬45°30'纬73°31'西 我有一个类,名为值的去向。 示例:Java 将Files.lines与.map一起使用(line->;line.split(";多个分隔符";),java,lambda,java-8,filestream,Java,Lambda,Java 8,Filestream,我有一个输入文件,格式如下: 安大略省:布兰顿:北纬43度41度79度45度西 安大略省:多伦多:43°39'北纬:79°23'西 魁北克:蒙特利尔:北纬45°30'纬73°31'西 我有一个类,名为值的去向。 示例: 省份:安大略省 城市:布兰顿 学位:43 上午:41 方向:N 长学位:79。。。。等 我已经完成了一个正确解析这个问题的方法,但我正在尝试了解使用Streams、Lambdas的Java8是否可以更好地解决这个问题 如果我从以下内容开始: Files.line(path.g
省份:安大略省 城市:布兰顿 学位:43 上午:41 方向:N 长学位:79。。。。等 我已经完成了一个正确解析这个问题的方法,但我正在尝试了解使用Streams、Lambdas的Java8是否可以更好地解决这个问题 如果我从以下内容开始:
Files.line(path.get(inputFile))
.map(line->line.split(“\\b+”)//这将分隔所有内容
//.filter(x->x.startsWith(“:”)
.flatMap(数组::流)
.forEach(System.out::println)代码>让我们从一些一般注释开始
您的序列.map(line->line.split(\\b+)).flatMap(Arrays::stream)
。这两个步骤将首先创建一个数组,然后再创建另一个封装该数组的流。您可以使用跳过数组步骤,但这要求您显式地处理模式,而不是将其隐藏在字符串中。拆分:
.flatMap(Pattern.compile("\\b+")::splitAsStream)
但请注意,在这种情况下,分裂成文字并没有真正的回报
如果您想保留原始的parseLine
方法,只需
Files.lines(Paths.get(inputFile))
.forEach(this::parseLine);
你完成了
但说真的,这不是一个真正的解决办法。要进行模式匹配,应使用指定用于模式匹配的库,例如。当您通过split(\\b+”)
进行拆分时,您已经在使用它了,但这远远落后于它所能为您提供的功能
让我们定义模式:
(…)
组成一个组,该组允许捕获匹配的部分,以便我们可以提取它以获得结果
[^:]*
指定由任意长度(*
)的冒号([^::]
)除外)以外的任意字符组成的标记
\d+
定义一个数字(d
=数字,+
=一个或多个)
[NS]
和[WE]
分别匹配N
或S
,或W
或E
所以你要寻找的整个模式是
([^:]*):([^:]*):(\d+)(\d+)([NS]):(\d+)(\d+)([WE])
整个解析例程将是:
static Pattern CITY_PATTERN=Pattern.compile(
"([^:]*):([^:]*):(\\d+)° (\\d+)' ([NS]):(\\d+)° (\\d+)' ([WE])");
static City parseCity(String line) {
Matcher matcher = CITY_PATTERN.matcher(line);
if(!matcher.matches())
throw new IllegalArgumentException(line+" doesn't match "+CITY_PATTERN);
City city=new City();
city.setProvince(matcher.group(1));
city.setCity(matcher.group(2));
city.setLatitudeDegrees(Integer.parseInt(matcher.group(3)));
city.setLatitudeMinutes(Integer.parseInt(matcher.group(4)));
city.setLatitudeDirection(line.charAt(matcher.start(5)));
city.setLongitudeDegrees(Integer.parseInt(matcher.group(6)));
city.setLongitudeMinutes(Integer.parseInt(matcher.group(7)));
city.setLongitudeDirection(line.charAt(matcher.start(8)));
return city;
}
我真的希望你把你的难懂的方法称为永远不要“浓缩”
使用上面的例程,一个干净的流
处理解决方案如下
List<City> cities = Files.lines(Paths.get(inputFile))
.map(ContainingClass::parseCity).collect(Collectors.toList());
List cities=Files.line(path.get(inputFile))
.map(包含class::parseCity).collect(Collectors.toList());
将文件收集到新的城市列表中。让我们从一些一般注释开始
您的序列.map(line->line.split(\\b+)).flatMap(Arrays::stream)
。这两个步骤将首先创建一个数组,然后再创建另一个封装该数组的流。您可以使用跳过数组步骤,但这要求您显式地处理模式,而不是将其隐藏在字符串中。拆分:
.flatMap(Pattern.compile("\\b+")::splitAsStream)
但请注意,在这种情况下,分裂成文字并没有真正的回报
如果您想保留原始的parseLine
方法,只需
Files.lines(Paths.get(inputFile))
.forEach(this::parseLine);
你完成了
但说真的,这不是一个真正的解决办法。要进行模式匹配,应使用指定用于模式匹配的库,例如。当您通过split(\\b+”)
进行拆分时,您已经在使用它了,但这远远落后于它所能为您提供的功能
让我们定义模式:
(…)
组成一个组,该组允许捕获匹配的部分,以便我们可以提取它以获得结果
[^:]*
指定由任意长度(*
)的冒号([^::]
)除外)以外的任意字符组成的标记
\d+
定义一个数字(d
=数字,+
=一个或多个)
[NS]
和[WE]
分别匹配N
或S
,或W
或E
所以你要寻找的整个模式是
([^:]*):([^:]*):(\d+)(\d+)([NS]):(\d+)(\d+)([WE])
整个解析例程将是:
static Pattern CITY_PATTERN=Pattern.compile(
"([^:]*):([^:]*):(\\d+)° (\\d+)' ([NS]):(\\d+)° (\\d+)' ([WE])");
static City parseCity(String line) {
Matcher matcher = CITY_PATTERN.matcher(line);
if(!matcher.matches())
throw new IllegalArgumentException(line+" doesn't match "+CITY_PATTERN);
City city=new City();
city.setProvince(matcher.group(1));
city.setCity(matcher.group(2));
city.setLatitudeDegrees(Integer.parseInt(matcher.group(3)));
city.setLatitudeMinutes(Integer.parseInt(matcher.group(4)));
city.setLatitudeDirection(line.charAt(matcher.start(5)));
city.setLongitudeDegrees(Integer.parseInt(matcher.group(6)));
city.setLongitudeMinutes(Integer.parseInt(matcher.group(7)));
city.setLongitudeDirection(line.charAt(matcher.start(8)));
return city;
}
我真的希望你把你的难懂的方法称为永远不要“浓缩”
使用上面的例程,一个干净的流
处理解决方案如下
List<City> cities = Files.lines(Paths.get(inputFile))
.map(ContainingClass::parseCity).collect(Collectors.toList());
List cities=Files.line(path.get(inputFile))
.map(包含class::parseCity).collect(Collectors.toList());
将文件收集到新的城市列表中。让我们从一些一般注释开始
您的序列.map(line->line.split(\\b+)).flatMap(Arrays::stream)
。这两个步骤将首先创建一个数组,然后再创建另一个封装该数组的流。您可以使用跳过数组步骤,但这要求您显式地处理模式,而不是将其隐藏在字符串中。拆分:
.flatMap(Pattern.compile("\\b+")::splitAsStream)
但请注意,在这种情况下,分裂成文字并没有真正的回报
如果您想保留原始的parseLine
方法,只需
Files.lines(Paths.get(inputFile))
.forEach(this::parseLine);
你完成了
但说真的,这不是一个真正的解决办法。要进行模式匹配,应使用指定用于模式匹配的库,例如。当您通过split(\\b+”)
进行拆分时,您已经在使用它了,但这远远落后于它所能为您提供的功能
让我们定义模式:
(…)
组成一个组,允许捕获matc