Reputation: 107
I'm creating a function that stores the List of Countries with the Code, Name and Flag (Image byte[]).
There are about 250 countries and even though my method only runs once, it seems highly inefficient.
This is a Maven Spring Project and the images are being loaded from /src/main/resources/images/flags
private void defaultCountries() throws IOException {
List<Country> countries = new ArrayList<>();
countries.add(new Country("AF", "Afghanistan", Files.readAllBytes(Paths.get("/images/flags/af.png"))));
... // All 250 countries
}
I'm copying the information from here manually https://github.com/yusufshakeel/mysql-country-with-flag
Can someone help me improve this?
Thanks
Upvotes: 2
Views: 95
Reputation: 15868
Your application is almost certainly "IO Bound", meaning that file IO (input/output) is slowing you down the most. There's only so much you can do, but there is at least one thing:
I suggest you put all your country flags in a single zip (uncompressed perhaps).
A non-trivial portion of file IO time is operating system overhead switching from one file to another. By assembling everything into a single file, you remove this overhead entirely. You'd then read in the zip, and pull out the individual parts you needed to build your images. Zip libraries have functions for accessing files within them, and Java's built-in zip handling is no different. Each zip entry has a name and a comment, so you might even be able to embed all your info into the entries and turn them into a little database.
I strongly recommend against hard-coding all the constants into your source and just reading out the images from equally hard-coded paths. It might work for this assignment. It might even be acceptable to your teacher. It is a terrible habit to get into if you want to be a professional programmer.
Upvotes: 2
Reputation: 1124
I'd use linked hash map as a container and java.util.Locale to get information about country:
private HashMap<String,Country> defaultCountries() {
return countriesWithFlags().collect(
LinkedHashMap::new,
(map,c) -> {try {
map.put(c[0], new Country(c[0], c[1], Files.readAllBytes(Paths.get(c[2]))));
} catch (IOException ignore) {}},
LinkedHashMap::putAll
);
}
private Stream<String[]> countriesWithFlags() {
return Arrays.stream(Locale.getISOCountries()).map(iso -> new Locale("", iso))
.map(l -> new String[]{
l.getCountry(),
l.getDisplayCountry(),
String.format("/images/flags/%s.png", l.getDisplayCountry().toLowerCase())
});
}
Unit test for countriesWithFlags:
package example;
import org.junit.Test;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.*;
public class ContryCodesTest {
final static Logger LOGGER = Logger.getLogger(ContryCodesTest.class.getName());
public static class Country{
public Country(String iso, String name, byte[] image) {
// FIXME
}
}
private HashMap<String,Country> defaultCountries() {
return countriesWithFlags().collect(
LinkedHashMap::new,
(map,c) -> {try {
map.put(c[0], new Country(c[0], c[1], Files.readAllBytes(Paths.get(c[2]))));
} catch (IOException ignore) {}},
LinkedHashMap::putAll
);
}
private Stream<String[]> countriesWithFlags() {
return Arrays.stream(Locale.getISOCountries()).map(iso -> new Locale("", iso))
.map(l -> new String[]{
l.getCountry(),
l.getDisplayCountry(),
String.format("/images/flags/%s.png", l.getDisplayCountry().toLowerCase())
});
}
@Test public void test() {
List<String[]> cwfs = countriesWithFlags().collect(Collectors.toList());
assertThat(cwfs, hasSize(250));
assertThat(cwfs.get(cwfs.size()-1)[2], equalTo("/images/flags/zimbabwe.png"));
}
}
Upvotes: 1