我想将String数组与具有市场对象的列表进行比较。
我实现了这样的代码:
private List<Data> addMarketData(List<Data> list) {
String[] SEE = new String[]{"Albania", "Bosnia and Herzegovina", "Bulgaria", "Croatia", "Macedonia FYR", "Moldavia", "Montenegro", "Romania", "Serbia", "Slovenia" };
List<String> seeList = Arrays.asList(SEE);
String[] CEE = new String[]{"Czech Republic", "Hungary", "Poland", "Slovakia"};
List<String> ceeList = Arrays.asList(CEE);
for (int i = 0; i < list.size(); i++) {
for (int j = 0; j < seeList.size(); j++) {
if(list.get(i).getPropertyCountry().equals(seeList.get(j).toString())) {
list.get(i).setMarket("SEE");
}
}
for (int k = 0; k < ceeList.size(); k++) {
if(list.get(i).getPropertyCountry().equals(ceeList.get(k).toString())) {
list.get(i).setMarket("CEE");
}
}
}
return list;
}
但是,我相信这段代码会产生比实际应用更多的开销。特别是for循环。我可以只使用一个循环吗?
因此,如何使这段代码更快?
感谢您的回答!
答案 0 :(得分:7)
将所有数据移至Set<String>
:
String[] SEE = ...
Set<String> setSEE = new HashSet<>(Arrays.asList(SEE));
String[] CEE = ...
Set<String> setCEE = new HashSet<>(Arrays.asList(CEE));
for (Data data : list) {
if (setSEE.contains(data.getPropertyCountry()) {
data.setMarket("SEE");
} else if (setCEE.contains(data.getPropertyCountry()) {
data.setMarket("CEE");
}
}
这不会产生您可能想到的开销。此外,它比您当前的O(N ^ 2)方法更快。
另一个想法是将这些数组的数据移动到@Narmer建议的Map<String, String>
,但在这种情况下,您应该在地图中找不到国家/地区时定义一个值。
从Java 7开始,您可以使用diamond operator。对于Java 5和6,您必须指定整个泛型用法:
Set<String> setSEE = new HashSet<String>(Arrays.asList(SEE));
//...
Set<String> setCEE = new HashSet<String>(Arrays.asList(CEE));
答案 1 :(得分:1)
您可以简单地使用两个HashSet<String>
集合来存储国家/地区的名称。HashSet<String>
每个项目大约 O(1)时间执行查找,这整个阵列的 O(n)。或者您可以使用一个HashMap<String,String>
执行查找,从而生成"SEE"
或"CEE"
。
示例强>
Map<String,String> lut = new HashMap<String,String>();
for(String s : new String[]{"Albania", "Bosnia and Herzegovina", "Bulgaria", "Croatia", "Macedonia FYR", "Moldavia", "Montenegro", "Romania", "Serbia", "Slovenia" }) {
lut.put(s,"SEE");
}
for(String s : new String[]{"Czech Republic", "Hungary", "Poland", "Slovakia"}) {
lut.put(s,"CEE");
}
for (Data data : list) {
data.setMarket(lut.get(data.getPropertyCountry()));
}
HashMap<String,String>
的生成(以及将数据放入其中)只应执行一次(启动时)。这将提高性能,其因子等于您放入HashMap<String,String>
的元素数量(在本例中为14)。
答案 2 :(得分:1)
您可以使用地图而不是列表。
private static final Map<String, String> markets = new HashMap<String,String>(){{
put("Albania", "SEE");
put("Bosnia and Herzegovina", "SEE");
...
put("Hungary", "CEE");
...
}}
然后咨询
for(Data data: list){
data.setMarket(markets.get(data.getPropertyCountry()));
}
修改强>
根据评论,以上是最佳情况。您应该检查data.getPropertyCountry()
是否为空(如果允许),并且列表返回的值也为空:
for(Data data: list){
if(data.getPropertyCountry()!=null){
String market = markets.get(data.getPropertyCountry());
data.setMarket(market==null?"default market":market);
}
else data.setMarket("default value"); //if needed
}
或者使用美丽的Java 8流接口:
for(Data data: list.stream().filter(p -> p.getPropertyCountry() != null).collect(Collectors.toList())){
String market = markets.get(data.getPropertyCountry());
data.setMarket(market==null?"default market":market);
}
答案 3 :(得分:1)
将seeList
和ceeList
定义为HashSet
,然后使用其contains()
方法。 HashSet
contains()
Set<String> seeSet = new HashSet<>();
Collections.addAll(seeSet, SEE);
Set<String> ceeSet = new HashSet<>();
Collections.addAll(ceeSet, CEE);
具有恒定的时间复杂度。
for (int i = 0; i < list.size(); i++) {
if (seeSet.contains(list.get(i).getPropertyCountry()) {
list.get(i).setMarket("SEE");
}
if (ceeSet.contains(list.get(i).getPropertyCountry()) {
list.get(i).setMarket("CEE");
}
}
然后:
{{1}}