Advertisement
Guest User

Untitled

a guest
May 26th, 2019
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 11.49 KB | None | 0 0
  1. package mountainhuts;
  2.  
  3. import static java.util.stream.Collectors.toList;
  4.  
  5. import java.io.BufferedReader;
  6. import java.io.FileReader;
  7. import java.io.IOException;
  8. import java.util.ArrayList;
  9. import java.util.Collection;
  10. import java.util.Collections;
  11. import java.util.Comparator;
  12. import java.util.HashMap;
  13. import java.util.HashSet;
  14. import java.util.Iterator;
  15. import java.util.List;
  16. import java.util.Map;
  17. import java.util.Optional;
  18. import java.util.TreeMap;
  19. import java.util.stream.Collectors;
  20. import java.util.stream.Stream;
  21.  
  22. public class Region {
  23.     private String name;
  24.     private Collection<Range> ranges;
  25.     private Collection<Municipality> municipalities;
  26.     private Collection<MountainHut> mountainHuts;
  27.  
  28.     /**
  29.      * Create a region with the given name.
  30.      *
  31.      * @param name
  32.      *            the name of the region
  33.      */
  34.     public Region(String name) {
  35.         this.name = name;
  36.         this.ranges = new ArrayList<>();
  37.         this.municipalities = new ArrayList<>();
  38.         this.mountainHuts = new ArrayList<>();
  39.     }
  40.  
  41.     /**
  42.      * Return the name of the region.
  43.      *
  44.      * @return the name of the region
  45.      */
  46.     public String getName() {
  47.         return this.name;
  48.     }
  49.  
  50.     /**
  51.      * Create the ranges given their textual representation in the format
  52.      * "[minValue]-[maxValue]".
  53.      *
  54.      * @param ranges
  55.      *            an array of textual ranges
  56.      */
  57.     public void setAltitudeRanges(String... ranges) {
  58.         for(String s : ranges) {
  59.              String[] temp = s.split("-");
  60.              this.ranges.add(new Range(Integer.parseInt(temp[0]),Integer.parseInt(temp[1])));
  61.         }
  62.     }
  63.    
  64.     /**
  65.      * Return the textual representation in the format "[minValue]-[maxValue]" of
  66.      * the range including the given altitude or return the default range "0-INF".
  67.      *
  68.      * @param altitude
  69.      *            the geographical altitude
  70.      * @return a string representing the range
  71.      */
  72.     public String getAltitudeRange(Integer altitude) {
  73.         for(Range r : ranges) {
  74.             if(r.isInRange(altitude))
  75.                 return r.toString();
  76.         }
  77.         return "0-INF";
  78.     }
  79.  
  80.     /**
  81.      * Return all the municipalities available.
  82.      *
  83.      * @return a collection of municipalities
  84.      */
  85.     public Collection<Municipality> getMunicipalities() {
  86.         return this.municipalities;
  87.     }
  88.  
  89.     /**
  90.      * Return all the mountain huts available.
  91.      *
  92.      * @return a collection of mountain huts
  93.      */
  94.     public Collection<MountainHut> getMountainHuts() {
  95.         return this.mountainHuts;
  96.     }
  97.  
  98.     /**
  99.      * Create a new municipality if it is not already available or find it.
  100.      * Duplicates must be detected by comparing the municipality names.
  101.      *
  102.      * @param name
  103.      *            the municipality name
  104.      * @param province
  105.      *            the municipality province
  106.      * @param altitude
  107.      *            the municipality altitude
  108.      * @return the municipality
  109.      */
  110.     public Municipality createOrGetMunicipality(String name, String province, Integer altitude) {
  111.        
  112.         Municipality mun = new Municipality (name,province,altitude);
  113.         for(Municipality m : municipalities) {
  114.             if(m.getName().compareTo(name) == 0)
  115.                 return m;
  116.         }
  117.         municipalities.add(mun);
  118.         return mun;
  119.     }
  120.  
  121.     /**
  122.      * Create a new mountain hut if it is not already available or find it.
  123.      * Duplicates must be detected by comparing the mountain hut names.
  124.      *
  125.      * @param name
  126.      *            the mountain hut name
  127.      * @param category
  128.      *            the mountain hut category
  129.      * @param bedsNumber
  130.      *            the number of beds in the mountain hut
  131.      * @param municipality
  132.      *            the municipality in which the mountain hut is located
  133.      * @return the mountain hut
  134.      */
  135.     public MountainHut createOrGetMountainHut(String name, String category, Integer bedsNumber,
  136.             Municipality municipality) {
  137.         return createOrGetMountainHut(name, null, category, bedsNumber, municipality);
  138.     }
  139.  
  140.     /**
  141.      * Create a new mountain hut if it is not already available or find it.
  142.      * Duplicates must be detected by comparing the mountain hut names.
  143.      *
  144.      * @param name
  145.      *            the mountain hut name
  146.      * @param altitude
  147.      *            the mountain hut altitude
  148.      * @param category
  149.      *            the mountain hut category
  150.      * @param bedsNumber
  151.      *            the number of beds in the mountain hut
  152.      * @param municipality
  153.      *            the municipality in which the mountain hut is located
  154.      * @return a mountain hut
  155.      */
  156.     public MountainHut createOrGetMountainHut(String name, Integer altitude, String category, Integer bedsNumber,
  157.             Municipality municipality) {
  158.        
  159.         MountainHut mouH = new MountainHut(name,category,municipality,Optional.ofNullable(altitude),bedsNumber);
  160.         for(MountainHut mh : mountainHuts) {
  161.             if(mh.getName().compareTo(name) == 0)
  162.                 return mh;
  163.         }
  164.         mountainHuts.add(mouH);
  165.         return mouH;
  166.     }
  167.  
  168.     /**
  169.      * Creates a new region and loads its data from a file.
  170.      *
  171.      * The file must be a CSV file and it must contain the following fields:
  172.      * <ul>
  173.      * <li>{@code "Province"},
  174.      * <li>{@code "Municipality"},
  175.      * <li>{@code "MunicipalityAltitude"},
  176.      * <li>{@code "Name"},
  177.      * <li>{@code "Altitude"},
  178.      * <li>{@code "Category"},
  179.      * <li>{@code "BedsNumber"}
  180.      * </ul>
  181.      *
  182.      * The fields are separated by a semicolon (';'). The field {@code "Altitude"}
  183.      * may be empty.
  184.      *
  185.      * @param name
  186.      *            the name of the region
  187.      * @param file
  188.      *            the path of the file
  189.      */
  190.     public static Region fromFile(String name, String file) {
  191.         Region region = new Region(name);
  192.         region.readData(file);
  193.         return region;
  194.     }
  195.  
  196.     @SuppressWarnings("unused")
  197.     private void readData(String file) {
  198.         List<String> lines = null;
  199.  
  200.         try (BufferedReader in = new BufferedReader(new FileReader(file))) {
  201.             lines = in.lines().collect(toList());
  202.         } catch (IOException e) {
  203.             System.err.println(e.getMessage());
  204.         }
  205.  
  206.         if (lines == null)
  207.             return;
  208.  
  209.         Iterator<String> iterator = lines.iterator();
  210.         String line = iterator.next();
  211.  
  212.         while(iterator.hasNext()) {
  213.             line = iterator.next();
  214.             String campi[] = line.split(";");
  215.             if(campi[4].compareTo("") == 0)
  216.                 campi[4] = campi[2];
  217.             this.createOrGetMountainHut(
  218.                     campi[3],
  219.                     new Integer(Integer.parseInt(campi[4])),
  220.                     campi[5],
  221.                     new Integer(Integer.parseInt(campi[6])),
  222.                     this.createOrGetMunicipality(campi[1], campi[0], new Integer(Integer.parseInt(campi[2]) )
  223.                             )
  224.                     );
  225.         }  
  226.     }
  227.  
  228.     /**
  229.      * Count the number of municipalities with at least a mountain hut per each
  230.      * province.
  231.      *
  232.      * @return a map with the province as key and the number of municipalities as
  233.      *         value
  234.      */
  235.     public Map<String, Long> countMunicipalitiesPerProvince() {
  236.         return municipalities.stream().collect(Collectors.groupingBy( Municipality :: getProvince,
  237.                 () -> new HashMap<>(), Collectors.counting() ) );
  238.     }
  239.  
  240.     /**
  241.      * Count the number of mountain huts per each municipality within each province.
  242.      *
  243.      * @return a map with the province as key and, as value, a map with the
  244.      *         municipality as key and the number of mountain huts as value
  245.      */
  246.     public Map<String, Map<String, Long>> countMountainHutsPerMunicipalityPerProvince() {
  247.         return mountainHuts.stream().collect(Collectors.groupingBy(
  248.                 m -> m.getMunicipality().getProvince(), () -> new HashMap<>(), Collectors.groupingBy(
  249.                         m-> m.getMunicipality().getName(),() -> new HashMap<>(), Collectors.counting()
  250.                         )
  251.                 )
  252.                 );
  253.     }
  254.  
  255.     /**
  256.      * Count the number of mountain huts per altitude range. If the altitude of the
  257.      * mountain hut is not available, use the altitude of its municipality.
  258.      *
  259.      * @return a map with the altitude range as key and the number of mountain huts
  260.      *         as value
  261.      */
  262.     public Map<String,Long> countMountainHutsPerAltitudeRange() {
  263.         return this.mountainHuts.stream().collect(Collectors.groupingBy(
  264.                 (MountainHut mh) -> {
  265.                     if(mh.getAltitude().isPresent())
  266.                         return this.getAltitudeRange(mh.getAltitude().get());
  267.                     else
  268.                         return this.getAltitudeRange(mh.getMunicipality().getAltitude());
  269.                 },
  270.                 () -> new HashMap<>(),
  271.                 Collectors.counting()
  272.                 )
  273.                 );
  274.     }
  275.        
  276.         /* Senza stream:
  277.          Map<String,Long> mappa = new HashMap<>();
  278.         Integer altezza;
  279.        
  280.         for(Range r : ranges) {
  281.             long conta = 0;
  282.             for(MountainHut m : mountainHuts) {
  283.                 if ( m.getAltitude().isPresent() )
  284.                     altezza = m.getAltitude().get();
  285.                 else
  286.                     altezza = m.getMunicipality().getAltitude();
  287.                
  288.                 if(r.isInRange(altezza) == true)
  289.                     conta++;
  290.             }
  291.             mappa.put(r.toString(), new Long(conta));
  292.         }
  293.         return mappa;
  294.     }*/
  295.  
  296.     /**
  297.      * Compute the total number of beds available in the mountain huts per each
  298.      * province.
  299.      *
  300.      * @return a map with the province as key and the total number of beds as value
  301.      */
  302.     public Map<String, Integer> totalBedsNumberPerProvince() {
  303.         return this.mountainHuts.stream().collect(Collectors.groupingBy(
  304.                 m -> m.getMunicipality().getProvince(), () -> new HashMap<>(), Collectors.summingInt(MountainHut :: getBedsNumber)
  305.                 )
  306.                 );
  307.     }
  308.  
  309.     /**
  310.      * Compute the maximum number of beds available in a single mountain hut per
  311.      * altitude range. If the altitude of the mountain hut is not available, use the
  312.      * altitude of its municipality.
  313.      *
  314.      * @return a map with the altitude range as key and the maximum number of beds
  315.      *         as value
  316.      */
  317.     public Map<String, Optional<Integer>> maximumBedsNumberPerAltitudeRange() {
  318.         return this.mountainHuts.stream().collect(Collectors.groupingBy(
  319.                 (MountainHut mh) -> {
  320.                     if(mh.getAltitude().isPresent())
  321.                         return this.getAltitudeRange(mh.getAltitude().get());
  322.                     else
  323.                         return this.getAltitudeRange(mh.getMunicipality().getAltitude());
  324.                 },
  325.                 () -> new HashMap<>(),
  326.                 Collectors.mapping(
  327.                         MountainHut :: getBedsNumber,
  328.                         Collectors.maxBy(Integer :: compareTo)
  329.                         )
  330.                 )
  331.                 );
  332.     }
  333.  
  334.         /*Senza stream:
  335.          Map<String,Optional<Integer>> mappa = new HashMap<>();
  336.          Integer altezza;
  337.        
  338.         for(Range r : ranges) {
  339.             int max = 0;
  340.             for(MountainHut mh : mountainHuts) {
  341.                 if ( mh.getAltitude().isPresent() )
  342.                     altezza = mh.getAltitude().get();
  343.                 else
  344.                     altezza = mh.getMunicipality().getAltitude();
  345.                
  346.                 int nBeds = mh.getBedsNumber();
  347.                 if(r.isInRange(altezza) && max < nBeds)
  348.                     max = nBeds;
  349.             }
  350.             mappa.put(r.toString(), Optional.ofNullable(max));
  351.         }
  352.         return mappa;/*
  353.     }
  354.  
  355.     /**
  356.      * Compute the municipality names per number of mountain huts in a municipality.
  357.      * The lists of municipality names must be in alphabetical order.
  358.      *
  359.      * @return a map with the number of mountain huts in a municipality as key and a
  360.      *         list of municipality names as value
  361.      */
  362.     public Map<Long, List<String>> municipalityNamesPerCountOfMountainHuts() {
  363.         /* Due stream separati
  364.         Map<String,Long> primaParte = this.mountainHuts.stream().collect( Collectors.groupingBy(
  365.                 (MountainHut mountainHut) -> mountainHut.getMunicipality().getName(),
  366.                 () -> new TreeMap<String,Long>(),
  367.                 Collectors.counting())
  368.                 );
  369.  
  370.         Map<Long, List<String>> secondaParte = primaParte.entrySet().stream().collect( Collectors.groupingBy(
  371.                 Map.Entry :: getValue,
  372.                 Collectors.mapping(
  373.                         Map.Entry :: getKey,  
  374.                         Collectors.toList() )
  375.                 )
  376.                 );
  377.         return secondaParte; */
  378.        
  379.         return this.mountainHuts.stream().collect( Collectors.groupingBy(
  380.                 (MountainHut mountainHut) -> mountainHut.getMunicipality().getName(), //classifier
  381.                 () -> new TreeMap<String,Long>(),
  382.                 Collectors.counting() //downstream
  383.                 ) ).entrySet().stream().collect( Collectors.groupingBy(
  384.                         Map.Entry :: getValue,
  385.                         Collectors.mapping(
  386.                                 Map.Entry :: getKey,
  387.                                 Collectors.toList()
  388.                                 )
  389.                         )
  390.                         );
  391.     }
  392. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement