java stream make map 经过两个不同的过滤器
java stream make map after two different filters
它应该return 一张地图。
这个地图的键应该是字符串“transversion”和“transition”,地图的值应该是SNP对象的列表。 “转换”是 A<->G 和 C<->T 之间的变化,“转换”是 A<->C、G<->T、A<->T 和 C<->G 之间的变化。
两个滤镜应该怎么制作?
public class StreamAssignment {
private static final List<Snp> SNP_COLLECTION = Snp.getSnpCollection();
private static final String[] SNP_DATA = new String[14];
static {
SNP_DATA[0] = "100273;A;G;0.0123";
SNP_DATA[1] = "100275;A;C;0.00323";
SNP_DATA[2] = "117807;T;G;0.1915";
SNP_DATA[3] = "162889;C;G;8.72E-4";
SNP_DATA[4] = "190199;T;C;0.1019";
SNP_DATA[5] = "277614;A;G;0.0168";
SNP_DATA[6] = "372778;C;A;4.24E-5";
SNP_DATA[7] = "417752;A;G;1.8474E-10";
SNP_DATA[8] = "478808;A;G;1.535689E-8";
SNP_DATA[9] = "556920;T;G;0.1097";
SNP_DATA[10] = "676255;G;C;0.0016672";
SNP_DATA[11] = "667280;A;G;0.00287";
SNP_DATA[12] = "719876;C;A;0.006649";
SNP_DATA[13] = "828771;A;C;0.097706";
}
public static Map<String, List<Snp>> getTransversionsTransitions() {
Map<String, List<Snp>> result;
result = SNP_COLLECTION.stream().filter();
return null;
}
}
snp class
package nl.bioinf.appdesign.d_streams_lambdas;
import java.util.ArrayList;
import java.util.List;
public class Snp {
private final long position;
private final char reference;
private final char alternative;
private final double minorAlleleFrequency;
public Snp(long position, char reference, char alternative, double minorAlleleFrequency) {
this.position = position;
this.reference = reference;
this.alternative = alternative;
this.minorAlleleFrequency = minorAlleleFrequency;
}
public long getPosition() {
return position;
}
public char getReference() {
return reference;
}
public char getAlternative() {
return alternative;
}
public double getMinorAlleleFrequency() {
return minorAlleleFrequency;
}
@Override
public String toString() {
return "Snp{" +
"position=" + position +
", reference=" + reference +
", alternative=" + alternative +
", minorAlleleFrequency=" + minorAlleleFrequency +
'}';
}
public final static List<Snp> getSnpCollection() {
List<Snp> snps = new ArrayList<>();
snps.add(new Snp(100273, 'A', 'G', 0.0123));
snps.add(new Snp(100275, 'A', 'C', 0.00323));
snps.add(new Snp(117807, 'T', 'G', 0.1915));
snps.add(new Snp(162889, 'C', 'G', 0.000872));
snps.add(new Snp(190199, 'T', 'C', 0.1019));
snps.add(new Snp(277614, 'A', 'G', 0.0168));
snps.add(new Snp(372778, 'C', 'A', 0.0000424));
snps.add(new Snp(417752, 'A', 'G', 1.8474e-10));
snps.add(new Snp(478808, 'A', 'G', 1.535689e-8));
snps.add(new Snp(556920, 'T', 'G', 0.1097));
snps.add(new Snp(676255, 'G', 'C', 1.6672e-3));
snps.add(new Snp(667280, 'A', 'G', 0.00287));
snps.add(new Snp(719876, 'C', 'A', 0.006649));
snps.add(new Snp(828771, 'A', 'C', 0.097706));
return snps;
}
}
由于您的 Snp
class 不包含有关它是转换还是颠换的信息,因此您需要一个包装器 class。我会省略它,但它只需要有一个 String type
属性、Snp snp
属性 和一个工厂方法(我们称之为解析)。
result = SNP_COLLECTION.stream()
// do your filtering based on string values
.map(SnpWrapper::parse) // String to Snp conversion
// do your filtering based on Snp values
.collect(Collectors.groupingBy(
Wrapper::getType,
Collectors.mapping(Wrapper::getSnp, Collectors.toList())
));
编辑:实际上不需要包装。您只需要提供一个实用方法。它可以放在 Snp
中,或者作为您当前 class 中的私有方法。让我们假设它是后者并且它被命名为 getSnpType
:
result = SNP_COLLECTION.stream()
// do your filtering based on string values
.map(Snp::parse) // or whatever you have for String -> Snp
// do your filtering based on Snp values
.collect(Collectors.groupingBy(StreamAssignment::getSnpType));
在 re-examining 你的代码和阅读你的解释之后,我假设 Snp
class 的属性 reference
和 alternative
是例如 A <-> C,其中 A 是参考,C 是备选。此外,您希望一组这些 Snp 实例用字符串“Transversions”标识,而另一个用“Transitions”标识。
这是我想出的代码。如果我误解了什么,请在评论中告诉我。
public static Map<String, List<Snp>> getTransversionsTransitions() {
Map<String, List<Snp>> result = new HashMap<>();
result.put("Transitions", SNP_COLLECTION.stream()
.filter(snp -> (snp.getReference() == 'A' && snp.getAlternative() == 'G') || (snp.getReference() == 'C' && snp.getAlternative() == 'T'))
.collect(Collectors.toList()));
result.put("Transversions", SNP_COLLECTION.stream()
.filter(snp -> (snp.getReference() == 'A' && snp.getAlternative() == 'C') || (snp.getReference() == 'G' && snp.getAlternative() == 'T')|| (snp.getReference() == 'C' && snp.getAlternative() == 'G'))
.collect(Collectors.toList()));
return result;
}
这只是检查输出是否符合您预期的主要步骤
public static void main(String[] args) {
Map<String, List<Snp>> result = getTransversionsTransitions();
for(String key: result.keySet()){
System.out.printf("%s => %s%n", key, result.get(key));
}
}
您可以将两个字符 reference
和 alternative
连接成一个字符串,然后使用正则表达式检查 transition
或 transversion
。像
import java.util.function.BiFunction;
....
public static Map<String, List<Snp>> getTransversionsTransitions() {
BiFunction<Character,Character,String> func =
(a,b) -> (""+a+b).matches("AG|GA|CT|TC") ? "Transitions":"Transversions";
return SNP_COLLECTION.stream()
.collect(Collectors.groupingBy(snp -> func.apply(snp.getReference(),snp.getAlternative())));
}
它应该return 一张地图。 这个地图的键应该是字符串“transversion”和“transition”,地图的值应该是SNP对象的列表。 “转换”是 A<->G 和 C<->T 之间的变化,“转换”是 A<->C、G<->T、A<->T 和 C<->G 之间的变化。
两个滤镜应该怎么制作?
public class StreamAssignment {
private static final List<Snp> SNP_COLLECTION = Snp.getSnpCollection();
private static final String[] SNP_DATA = new String[14];
static {
SNP_DATA[0] = "100273;A;G;0.0123";
SNP_DATA[1] = "100275;A;C;0.00323";
SNP_DATA[2] = "117807;T;G;0.1915";
SNP_DATA[3] = "162889;C;G;8.72E-4";
SNP_DATA[4] = "190199;T;C;0.1019";
SNP_DATA[5] = "277614;A;G;0.0168";
SNP_DATA[6] = "372778;C;A;4.24E-5";
SNP_DATA[7] = "417752;A;G;1.8474E-10";
SNP_DATA[8] = "478808;A;G;1.535689E-8";
SNP_DATA[9] = "556920;T;G;0.1097";
SNP_DATA[10] = "676255;G;C;0.0016672";
SNP_DATA[11] = "667280;A;G;0.00287";
SNP_DATA[12] = "719876;C;A;0.006649";
SNP_DATA[13] = "828771;A;C;0.097706";
}
public static Map<String, List<Snp>> getTransversionsTransitions() {
Map<String, List<Snp>> result;
result = SNP_COLLECTION.stream().filter();
return null;
}
}
snp class
package nl.bioinf.appdesign.d_streams_lambdas;
import java.util.ArrayList;
import java.util.List;
public class Snp {
private final long position;
private final char reference;
private final char alternative;
private final double minorAlleleFrequency;
public Snp(long position, char reference, char alternative, double minorAlleleFrequency) {
this.position = position;
this.reference = reference;
this.alternative = alternative;
this.minorAlleleFrequency = minorAlleleFrequency;
}
public long getPosition() {
return position;
}
public char getReference() {
return reference;
}
public char getAlternative() {
return alternative;
}
public double getMinorAlleleFrequency() {
return minorAlleleFrequency;
}
@Override
public String toString() {
return "Snp{" +
"position=" + position +
", reference=" + reference +
", alternative=" + alternative +
", minorAlleleFrequency=" + minorAlleleFrequency +
'}';
}
public final static List<Snp> getSnpCollection() {
List<Snp> snps = new ArrayList<>();
snps.add(new Snp(100273, 'A', 'G', 0.0123));
snps.add(new Snp(100275, 'A', 'C', 0.00323));
snps.add(new Snp(117807, 'T', 'G', 0.1915));
snps.add(new Snp(162889, 'C', 'G', 0.000872));
snps.add(new Snp(190199, 'T', 'C', 0.1019));
snps.add(new Snp(277614, 'A', 'G', 0.0168));
snps.add(new Snp(372778, 'C', 'A', 0.0000424));
snps.add(new Snp(417752, 'A', 'G', 1.8474e-10));
snps.add(new Snp(478808, 'A', 'G', 1.535689e-8));
snps.add(new Snp(556920, 'T', 'G', 0.1097));
snps.add(new Snp(676255, 'G', 'C', 1.6672e-3));
snps.add(new Snp(667280, 'A', 'G', 0.00287));
snps.add(new Snp(719876, 'C', 'A', 0.006649));
snps.add(new Snp(828771, 'A', 'C', 0.097706));
return snps;
}
}
由于您的 Snp
class 不包含有关它是转换还是颠换的信息,因此您需要一个包装器 class。我会省略它,但它只需要有一个 String type
属性、Snp snp
属性 和一个工厂方法(我们称之为解析)。
result = SNP_COLLECTION.stream()
// do your filtering based on string values
.map(SnpWrapper::parse) // String to Snp conversion
// do your filtering based on Snp values
.collect(Collectors.groupingBy(
Wrapper::getType,
Collectors.mapping(Wrapper::getSnp, Collectors.toList())
));
编辑:实际上不需要包装。您只需要提供一个实用方法。它可以放在 Snp
中,或者作为您当前 class 中的私有方法。让我们假设它是后者并且它被命名为 getSnpType
:
result = SNP_COLLECTION.stream()
// do your filtering based on string values
.map(Snp::parse) // or whatever you have for String -> Snp
// do your filtering based on Snp values
.collect(Collectors.groupingBy(StreamAssignment::getSnpType));
在 re-examining 你的代码和阅读你的解释之后,我假设 Snp
class 的属性 reference
和 alternative
是例如 A <-> C,其中 A 是参考,C 是备选。此外,您希望一组这些 Snp 实例用字符串“Transversions”标识,而另一个用“Transitions”标识。
这是我想出的代码。如果我误解了什么,请在评论中告诉我。
public static Map<String, List<Snp>> getTransversionsTransitions() {
Map<String, List<Snp>> result = new HashMap<>();
result.put("Transitions", SNP_COLLECTION.stream()
.filter(snp -> (snp.getReference() == 'A' && snp.getAlternative() == 'G') || (snp.getReference() == 'C' && snp.getAlternative() == 'T'))
.collect(Collectors.toList()));
result.put("Transversions", SNP_COLLECTION.stream()
.filter(snp -> (snp.getReference() == 'A' && snp.getAlternative() == 'C') || (snp.getReference() == 'G' && snp.getAlternative() == 'T')|| (snp.getReference() == 'C' && snp.getAlternative() == 'G'))
.collect(Collectors.toList()));
return result;
}
这只是检查输出是否符合您预期的主要步骤
public static void main(String[] args) {
Map<String, List<Snp>> result = getTransversionsTransitions();
for(String key: result.keySet()){
System.out.printf("%s => %s%n", key, result.get(key));
}
}
您可以将两个字符 reference
和 alternative
连接成一个字符串,然后使用正则表达式检查 transition
或 transversion
。像
import java.util.function.BiFunction;
....
public static Map<String, List<Snp>> getTransversionsTransitions() {
BiFunction<Character,Character,String> func =
(a,b) -> (""+a+b).matches("AG|GA|CT|TC") ? "Transitions":"Transversions";
return SNP_COLLECTION.stream()
.collect(Collectors.groupingBy(snp -> func.apply(snp.getReference(),snp.getAlternative())));
}