From e90e242bbd461a8394e693ac886b794991c6563a Mon Sep 17 00:00:00 2001
From: laame
Date: Fri, 1 Apr 2022 11:24:39 +0300
Subject: [PATCH 1/2] RestCountries up to 3a
---
.../assignments/restcountries/Country.java | 65 +++
.../assignments/restcountries/README.md | 24 +
.../restcountries/RestCountries.java | 102 ++++
.../restcountries/eu-countries.json | 440 ++++++++++++++++++
4 files changed, 631 insertions(+)
create mode 100644 src/main/java/io/codelex/assignments/restcountries/Country.java
create mode 100644 src/main/java/io/codelex/assignments/restcountries/README.md
create mode 100644 src/main/java/io/codelex/assignments/restcountries/RestCountries.java
create mode 100644 src/main/resources/io/codelex/assignments/restcountries/eu-countries.json
diff --git a/src/main/java/io/codelex/assignments/restcountries/Country.java b/src/main/java/io/codelex/assignments/restcountries/Country.java
new file mode 100644
index 0000000..6218aa7
--- /dev/null
+++ b/src/main/java/io/codelex/assignments/restcountries/Country.java
@@ -0,0 +1,65 @@
+package io.codelex.assignments.restcountries;
+
+import java.util.Currency;
+import java.util.HashSet;
+import java.util.Set;
+
+public class Country {
+ private final String name;
+ private String capital;
+ private int population;
+ private double area;
+ private Set currencies = new HashSet<>();
+
+
+ public Country(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getCapital() {
+ return capital;
+ }
+
+ public void setCapital(String capital) {
+ this.capital = capital;
+ }
+
+ public int getPopulation() {
+ return population;
+ }
+
+ public void setPopulation(int population) {
+ this.population = population;
+ }
+
+ public double getArea() {
+ return area;
+ }
+
+ public void setArea(double area) {
+ this.area = area;
+ }
+
+ public Set getCurrencies() {
+ return currencies;
+ }
+
+ public void addCurrency(String code) {
+ if (code.length() == 3) {
+ Currency currency = Currency.getInstance(code);
+ currencies.add(currency);
+ }
+ }
+
+ public double getDensity() {
+ if (getPopulation() != 0 && getArea() != 0) {
+ return (getPopulation() / getArea());
+ }
+ return 0.0;
+ }
+
+}
diff --git a/src/main/java/io/codelex/assignments/restcountries/README.md b/src/main/java/io/codelex/assignments/restcountries/README.md
new file mode 100644
index 0000000..4554555
--- /dev/null
+++ b/src/main/java/io/codelex/assignments/restcountries/README.md
@@ -0,0 +1,24 @@
+## Task
+---
+
+1. Using restcountries.eu create a text data file in JSON format, containing only the
+following data about countries in the European Union: name, capital, currencies, population,
+area.
+
+2. Read and process this file with your java program to get the following results:
+
+- top 10 countries with the biggest population
+- top 10 countries with the biggest area
+- top 10 countries with the biggest population density (people / square km)
+3a. Add the ability to consume the data about countries directly from the restcountries.eu and
+process it (keep the code that processes data from the text file as well!)
+3b. Convert your application to Spring Boot application and expose results via REST API
+4. Add unit tests
+Additional info:
+1. and 2. are mandatory.
+3a. and 3b. are very good to have, can be done in any order
+4. is optional, but nice to have. do not be shy to try :)
+Deliverables:
+1. source code
+2. description how to run your program - i.e. how do you run it yourself. it might be using IDE, or
+a using command line, whatever works
diff --git a/src/main/java/io/codelex/assignments/restcountries/RestCountries.java b/src/main/java/io/codelex/assignments/restcountries/RestCountries.java
new file mode 100644
index 0000000..a98dab0
--- /dev/null
+++ b/src/main/java/io/codelex/assignments/restcountries/RestCountries.java
@@ -0,0 +1,102 @@
+package io.codelex.assignments.restcountries;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
+public class RestCountries {
+ public static void main(String[] args) throws IOException {
+ String jsonData = getRestCountriesJsonData();
+ List countries = parseRestCountriesJsonData(jsonData);
+
+ System.out.println("Top 10 by population:");
+ List top10pop = countries.stream()
+ .sorted(Comparator.comparingInt(Country::getPopulation).reversed())
+ .limit(10L)
+ .map(country -> country.getName() + '\t' + country.getPopulation())
+ .toList();
+
+ top10pop.forEach(System.out::println);
+
+ System.out.println();
+ System.out.println("Top 10 by area:");
+ List top10area = countries.stream()
+ .filter(country -> country.getArea() != 0)
+ .sorted(Comparator.comparingDouble(Country::getArea).reversed())
+ .limit(10L)
+ .map(country -> country.getName() + '\t' + country.getArea())
+ .toList();
+ top10area.forEach(System.out::println);
+
+ System.out.println();
+ System.out.println("Top 10 by density");
+ List top10density = countries.stream()
+ .filter(country -> country.getDensity() != 0.0)
+ .sorted(Comparator.comparing(Country::getDensity).reversed())
+ .limit(10L)
+ .map(country -> String.format("%s\t%.2f", country.getName(), country.getDensity()))
+ .toList();
+
+ top10density.forEach(System.out::println);
+
+ }
+
+ private static String getLocalRestCountriesJsonData() throws IOException {
+ Path fileName = Path.of(Country.class.getResource("eu-countries.json").getPath());
+ return Files.readString(fileName);
+ }
+
+ private static String getRestCountriesJsonData() {
+ try {
+ URL url = new URL("https://restcountries.com/v2/regionalbloc/eu?fields=name,capital,currencies,population,area");
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("GET");
+ connection.connect();
+ int responseCode = connection.getResponseCode();
+ if (responseCode != 200) {
+ throw new RuntimeException("HttpResponseCode: " + responseCode);
+ } else {
+ StringBuilder builder = new StringBuilder();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
+ String inputLine;
+ while ((inputLine = reader.readLine()) != null) {
+ builder.append(inputLine);
+ }
+ return builder.toString();
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+
+ private static List parseRestCountriesJsonData(String jsonData) {
+ List countries = new ArrayList<>();
+ JSONArray jsonArr = new JSONArray(jsonData);
+ for (Object countryObj : jsonArr) {
+ JSONObject countryJson = (JSONObject) countryObj;
+ Country country = new Country(countryJson.getString("name"));
+ country.setCapital(countryJson.getString("capital"));
+ country.setPopulation(countryJson.getInt("population"));
+ if (countryJson.has("area")) {
+ country.setArea(countryJson.getDouble("area"));
+ }
+ for (Object currencyObj : countryJson.getJSONArray("currencies")) {
+ JSONObject currencyJson = (JSONObject) currencyObj;
+ country.addCurrency(currencyJson.getString("code"));
+ }
+ countries.add(country);
+ }
+ return countries;
+ }
+
+}
diff --git a/src/main/resources/io/codelex/assignments/restcountries/eu-countries.json b/src/main/resources/io/codelex/assignments/restcountries/eu-countries.json
new file mode 100644
index 0000000..53f6994
--- /dev/null
+++ b/src/main/resources/io/codelex/assignments/restcountries/eu-countries.json
@@ -0,0 +1,440 @@
+[
+ {
+ "name": "Åland Islands",
+ "capital": "Mariehamn",
+ "population": 28875,
+ "area": 1580.0,
+ "currencies": [
+ {
+ "code": "EUR",
+ "name": "Euro",
+ "symbol": "€"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Austria",
+ "capital": "Vienna",
+ "population": 8917205,
+ "area": 83871.0,
+ "currencies": [
+ {
+ "code": "EUR",
+ "name": "Euro",
+ "symbol": "€"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Belgium",
+ "capital": "Brussels",
+ "population": 11555997,
+ "area": 30528.0,
+ "currencies": [
+ {
+ "code": "EUR",
+ "name": "Euro",
+ "symbol": "€"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Bulgaria",
+ "capital": "Sofia",
+ "population": 6927288,
+ "area": 110879.0,
+ "currencies": [
+ {
+ "code": "BGN",
+ "name": "Bulgarian lev",
+ "symbol": "лв"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Croatia",
+ "capital": "Zagreb",
+ "population": 4047200,
+ "area": 56594.0,
+ "currencies": [
+ {
+ "code": "HRK",
+ "name": "Croatian kuna",
+ "symbol": "kn"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Cyprus",
+ "capital": "Nicosia",
+ "population": 1207361,
+ "area": 9251.0,
+ "currencies": [
+ {
+ "code": "EUR",
+ "name": "Euro",
+ "symbol": "€"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Czech Republic",
+ "capital": "Prague",
+ "population": 10698896,
+ "area": 78865.0,
+ "currencies": [
+ {
+ "code": "CZK",
+ "name": "Czech koruna",
+ "symbol": "Kč"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Denmark",
+ "capital": "Copenhagen",
+ "population": 5831404,
+ "area": 43094.0,
+ "currencies": [
+ {
+ "code": "DKK",
+ "name": "Danish krone",
+ "symbol": "kr"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Estonia",
+ "capital": "Tallinn",
+ "population": 1331057,
+ "area": 45227.0,
+ "currencies": [
+ {
+ "code": "EUR",
+ "name": "Euro",
+ "symbol": "€"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Finland",
+ "capital": "Helsinki",
+ "population": 5530719,
+ "area": 338424.0,
+ "currencies": [
+ {
+ "code": "EUR",
+ "name": "Euro",
+ "symbol": "€"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "France",
+ "capital": "Paris",
+ "population": 67391582,
+ "area": 640679.0,
+ "currencies": [
+ {
+ "code": "EUR",
+ "name": "Euro",
+ "symbol": "€"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "French Guiana",
+ "capital": "Cayenne",
+ "population": 254541,
+ "currencies": [
+ {
+ "code": "EUR",
+ "name": "Euro",
+ "symbol": "€"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Germany",
+ "capital": "Berlin",
+ "population": 83240525,
+ "area": 357114.0,
+ "currencies": [
+ {
+ "code": "EUR",
+ "name": "Euro",
+ "symbol": "€"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Gibraltar",
+ "capital": "Gibraltar",
+ "population": 33691,
+ "area": 6.0,
+ "currencies": [
+ {
+ "code": "GIP",
+ "name": "Gibraltar pound",
+ "symbol": "£"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Greece",
+ "capital": "Athens",
+ "population": 10715549,
+ "area": 131990.0,
+ "currencies": [
+ {
+ "code": "EUR",
+ "name": "Euro",
+ "symbol": "€"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Hungary",
+ "capital": "Budapest",
+ "population": 9749763,
+ "area": 93028.0,
+ "currencies": [
+ {
+ "code": "HUF",
+ "name": "Hungarian forint",
+ "symbol": "Ft"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Ireland",
+ "capital": "Dublin",
+ "population": 4994724,
+ "area": 70273.0,
+ "currencies": [
+ {
+ "code": "EUR",
+ "name": "Euro",
+ "symbol": "€"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Isle of Man",
+ "capital": "Douglas",
+ "population": 85032,
+ "area": 572.0,
+ "currencies": [
+ {
+ "code": "GBP",
+ "name": "British pound",
+ "symbol": "£"
+ },
+ {
+ "code": "IMP[G]",
+ "name": "Manx pound",
+ "symbol": "£"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Italy",
+ "capital": "Rome",
+ "population": 59554023,
+ "area": 301336.0,
+ "currencies": [
+ {
+ "code": "EUR",
+ "name": "Euro",
+ "symbol": "€"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Latvia",
+ "capital": "Riga",
+ "population": 1901548,
+ "area": 64559.0,
+ "currencies": [
+ {
+ "code": "EUR",
+ "name": "Euro",
+ "symbol": "€"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Lithuania",
+ "capital": "Vilnius",
+ "population": 2794700,
+ "area": 65300.0,
+ "currencies": [
+ {
+ "code": "EUR",
+ "name": "Euro",
+ "symbol": "€"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Luxembourg",
+ "capital": "Luxembourg",
+ "population": 632275,
+ "area": 2586.0,
+ "currencies": [
+ {
+ "code": "EUR",
+ "name": "Euro",
+ "symbol": "€"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Malta",
+ "capital": "Valletta",
+ "population": 525285,
+ "area": 316.0,
+ "currencies": [
+ {
+ "code": "EUR",
+ "name": "Euro",
+ "symbol": "€"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Netherlands",
+ "capital": "Amsterdam",
+ "population": 17441139,
+ "area": 41850.0,
+ "currencies": [
+ {
+ "code": "EUR",
+ "name": "Euro",
+ "symbol": "€"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Poland",
+ "capital": "Warsaw",
+ "population": 37950802,
+ "area": 312679.0,
+ "currencies": [
+ {
+ "code": "PLN",
+ "name": "Polish złoty",
+ "symbol": "zł"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Portugal",
+ "capital": "Lisbon",
+ "population": 10305564,
+ "area": 92090.0,
+ "currencies": [
+ {
+ "code": "EUR",
+ "name": "Euro",
+ "symbol": "€"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Romania",
+ "capital": "Bucharest",
+ "population": 19286123,
+ "area": 238391.0,
+ "currencies": [
+ {
+ "code": "RON",
+ "name": "Romanian leu",
+ "symbol": "lei"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Slovakia",
+ "capital": "Bratislava",
+ "population": 5458827,
+ "area": 49037.0,
+ "currencies": [
+ {
+ "code": "EUR",
+ "name": "Euro",
+ "symbol": "€"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Slovenia",
+ "capital": "Ljubljana",
+ "population": 2100126,
+ "area": 20273.0,
+ "currencies": [
+ {
+ "code": "EUR",
+ "name": "Euro",
+ "symbol": "€"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Spain",
+ "capital": "Madrid",
+ "population": 47351567,
+ "area": 505992.0,
+ "currencies": [
+ {
+ "code": "EUR",
+ "name": "Euro",
+ "symbol": "€"
+ }
+ ],
+ "independent": false
+ },
+ {
+ "name": "Sweden",
+ "capital": "Stockholm",
+ "population": 10353442,
+ "area": 450295.0,
+ "currencies": [
+ {
+ "code": "SEK",
+ "name": "Swedish krona",
+ "symbol": "kr"
+ }
+ ],
+ "independent": false
+ }
+]
From c7561f18c1cf77d209d29d8511ac87d01bf4b5aa Mon Sep 17 00:00:00 2001
From: Pukkah
Date: Mon, 4 Apr 2022 23:42:38 +0300
Subject: [PATCH 2/2] Custom Currency class for RestCountries
---
.../assignments/restcountries/Country.java | 17 ++++--
.../assignments/restcountries/Currency.java | 61 +++++++++++++++++++
.../restcountries/RestCountries.java | 24 ++++----
3 files changed, 86 insertions(+), 16 deletions(-)
create mode 100644 src/main/java/io/codelex/assignments/restcountries/Currency.java
diff --git a/src/main/java/io/codelex/assignments/restcountries/Country.java b/src/main/java/io/codelex/assignments/restcountries/Country.java
index 6218aa7..eb1d7b1 100644
--- a/src/main/java/io/codelex/assignments/restcountries/Country.java
+++ b/src/main/java/io/codelex/assignments/restcountries/Country.java
@@ -1,6 +1,5 @@
package io.codelex.assignments.restcountries;
-import java.util.Currency;
import java.util.HashSet;
import java.util.Set;
@@ -48,11 +47,8 @@ public Set getCurrencies() {
return currencies;
}
- public void addCurrency(String code) {
- if (code.length() == 3) {
- Currency currency = Currency.getInstance(code);
+ public void addCurrency(Currency currency) {
currencies.add(currency);
- }
}
public double getDensity() {
@@ -62,4 +58,15 @@ public double getDensity() {
return 0.0;
}
+ @Override
+ public String toString() {
+ return "Country{" +
+ "name='" + name + '\'' +
+ ", capital='" + capital + '\'' +
+ ", population=" + population +
+ ", area=" + area +
+ ", currencies=" + currencies +
+ '}';
+ }
+
}
diff --git a/src/main/java/io/codelex/assignments/restcountries/Currency.java b/src/main/java/io/codelex/assignments/restcountries/Currency.java
new file mode 100644
index 0000000..45ea83a
--- /dev/null
+++ b/src/main/java/io/codelex/assignments/restcountries/Currency.java
@@ -0,0 +1,61 @@
+package io.codelex.assignments.restcountries;
+
+import java.util.Objects;
+
+public class Currency {
+ private final String code;
+ private final String name;
+ private final String symbol;
+
+ public Currency(String code, String name, String symbol) {
+ this.code = code;
+ this.name = name;
+ this.symbol = symbol;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getSymbol() {
+ return symbol;
+ }
+
+ @Override
+ public String toString() {
+ return code + " \"" + name + "\" " + symbol;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ Currency currency = (Currency) o;
+
+ if (!Objects.equals(code, currency.code)) {
+ return false;
+ }
+ if (!Objects.equals(name, currency.name)) {
+ return false;
+ }
+ return Objects.equals(symbol, currency.symbol);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = code != null ? code.hashCode() : 0;
+ result = 31 * result + (name != null ? name.hashCode() : 0);
+ result = 31 * result + (symbol != null ? symbol.hashCode() : 0);
+ return result;
+ }
+
+}
diff --git a/src/main/java/io/codelex/assignments/restcountries/RestCountries.java b/src/main/java/io/codelex/assignments/restcountries/RestCountries.java
index a98dab0..6b76d5a 100644
--- a/src/main/java/io/codelex/assignments/restcountries/RestCountries.java
+++ b/src/main/java/io/codelex/assignments/restcountries/RestCountries.java
@@ -20,35 +20,33 @@ public static void main(String[] args) throws IOException {
List countries = parseRestCountriesJsonData(jsonData);
System.out.println("Top 10 by population:");
- List top10pop = countries.stream()
- .sorted(Comparator.comparingInt(Country::getPopulation).reversed())
+ List top10pop = countries.stream()
+ .sorted(Comparator.comparing(Country::getPopulation).reversed())
.limit(10L)
- .map(country -> country.getName() + '\t' + country.getPopulation())
.toList();
-
top10pop.forEach(System.out::println);
System.out.println();
System.out.println("Top 10 by area:");
- List top10area = countries.stream()
+ List top10area = countries.stream()
.filter(country -> country.getArea() != 0)
- .sorted(Comparator.comparingDouble(Country::getArea).reversed())
+ .sorted(Comparator.comparing(Country::getArea).reversed())
.limit(10L)
- .map(country -> country.getName() + '\t' + country.getArea())
.toList();
top10area.forEach(System.out::println);
System.out.println();
System.out.println("Top 10 by density");
- List top10density = countries.stream()
+ List top10density = countries.stream()
.filter(country -> country.getDensity() != 0.0)
.sorted(Comparator.comparing(Country::getDensity).reversed())
.limit(10L)
- .map(country -> String.format("%s\t%.2f", country.getName(), country.getDensity()))
.toList();
-
top10density.forEach(System.out::println);
+ System.out.println();
+ System.out.println("Listing all Countries");
+ countries.forEach(System.out::println);
}
private static String getLocalRestCountriesJsonData() throws IOException {
@@ -92,7 +90,11 @@ private static List parseRestCountriesJsonData(String jsonData) {
}
for (Object currencyObj : countryJson.getJSONArray("currencies")) {
JSONObject currencyJson = (JSONObject) currencyObj;
- country.addCurrency(currencyJson.getString("code"));
+ String code = currencyJson.getString("code");
+ String name = currencyJson.getString("name");
+ String symbol = currencyJson.getString("symbol");
+ Currency currency = new Currency(code, name, symbol);
+ country.addCurrency(currency);
}
countries.add(country);
}