I try to get a list of all available countries and currencies at the same time. I want the country names to be on spinner and when user chooses the country it's return the currency symbol. My method works but i think it's very bad practice because it's take like 3-2 sec to load the data. I did it like this:
public ArrayList<CurrencyModel> getCountriesAndCurrency(){
ArrayList<CurrencyModel> result = new ArrayList<>();
ArrayList<Locale> list = new ArrayList<>(Arrays.asList(Locale.getAvailableLocales()));
for (int i = 0; i <list.size(); i++) {
String country = list.get(i).getDisplayCountry();
try {
Locale pickedLocal = new Locale(list.get(i).getISO3Language(), list.get(i).getCountry());
String code = Currency.getInstance(pickedLocal).getCurrencyCode();
Currency currency = Currency.getInstance(code);
String currencySymbol = currency.getSymbol(pickedLocal);
if(currencySymbol.length()>1){
currencySymbol = currency.getSymbol();
}
result.add(new CurrencyModel(list.get(i), country, currencySymbol));
} catch (Exception e) {
}
}
Collections.sort(result, new CustomComparator());
ArrayList<CurrencyModel> finalRes = new ArrayList<>();
for (int i = 0; i < result.size(); i++) {
try {
if(!result.get(i).getCountryName().equals(result.get((i+1)).getCountryName())) {
finalRes.add(result.get(i));
}
}catch (Exception e){}
}
Collections.sort(finalRes, new CustomComparator());
return finalRes;
}
public class CustomComparator implements Comparator<CurrencyModel> {
@Override
public int compare(CurrencyModel o1, CurrencyModel o2) {
return o1.getCountryName().compareTo(o2.getCountryName());
}
}
CurrencyModel object is = locale locale ,String countryName , String currencySymbol.
there is better solution for this action?
found couple of things could help you not sure though if they will significantly enhance the result
1- Locale re-instantiate
Locale pickedLocal = new Locale(list.get(i).getISO3Language(), list.get(i).getCountry());
why you recreate the locale , using a locale
attributes?
you just have to assign it:
Locale pickedLocal = list.get(i);
2- same for Currency,
String code = Currency.getInstance(pickedLocal).getCurrencyCode();
Currency currency = Currency.getInstance(code);
String currencySymbol = currency.getSymbol(pickedLocal);
as i understand, your target is getting currencySymbol
, so just do it like this:
String currencySymbol = Currency.getInstance(pickedLocal).getSymbol();
so the final block of code (the one with try-catch) should look like this
try {
Locale pickedLocal = list.get(i);
String currencySymbol = Currency.getInstance(pickedLocal).getSymbol();
if(currencySymbol.length()>1){
currencySymbol = currency.getSymbol();
}
result.add(new CurrencyModel(pickedLocal, country, currencySymbol));
} catch (Exception e) {
}
at result.add(new CurrencyModel(list.get(i),...
use pickedLocal, don't re-get item from the list.
that's what i got so far, i will append any further finds to this answer.
EDIT: (maybe you will have to sort the mail "list" first) a second look into the code, i found that you try to remove duplicates after you populate results list, if you check the result list before adding new item, you will get rid of the second loop
try {
Locale pickedLocal = list.get(i);
String currencySymbol = Currency.getInstance(pickedLocal).getSymbol();
if(currencySymbol.length()>1){
currencySymbol = currency.getSymbol();
}
//TO AVOID the second loop (check duplicates), add only if not exist
final int size = result.size();
if(size > 0){
if(!result.get(size-1).getCountryName().equals(country)){
//no similar item was added yet, so add the new item
result.add(new CurrencyModel(pickedLocal, country, currencySymbol));
}
}else{
//it still empty, just add the new item
result.add(new CurrencyModel(pickedLocal, country, currencySymbol));
}
} catch (Exception e) {
}