Home > database >  java stream make map after two different filters
java stream make map after two different filters

Time:04-18

It should return a Map. Keys of this Map should be the Strings "transversion" and "transition", and the values of the Map should be lists of SNP objects. "Transitions" are changes between A<->G and C<->T and "transversions" are changes A<->C, G<->T, A<->T and C<->G.

How should I make the two filters?

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;
    }
}

CodePudding user response:

Since your Snp class doesn't contain information about whether it's a transition or transversion, you would need a wrapper class. I'll omit that, but it just needs to have a String type property, Snp snp property, and a factory method (let's call it parse).

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())
        ));

Edit: the wrapping is actually not needed. You'll just need to provide a utility method. That can be placed in Snp, or as a private method in your current class. Let's assume it's the latter and it's named 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));

CodePudding user response:

After re-examining your code and reading your explanations, I have assumed that the properties reference and alternative of the Snp class are to be intended as for example A <-> C where A is the reference and C the alternative. Furthermore, You want a group of these Snp instances being identified with the String "Transversions" while another with "Transitions".

This is the code that I've come up with. Let me know in the comments if I've misinterpreted something.

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;
}

This is just a main to check if the output is what you expected

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));
    }
}

CodePudding user response:

You could concat your two chars reference & alternative to a string and use regex to check for transition or transversion. Something like

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())));
}
  • Related