我有以下格式的JSON响应,我将解析它以获取每个键的键(key_as_String)和值(Expected_Usage和Actual_Usage)。
"aggregations": {
"Inner_aggregation": {
"doc_count": 366,
"Hours_aggregation": {
"doc_count": 366,
"by_day": {
"buckets": [
{
"key_as_string": "2016-01-11",
"key": 1452556800000,
"doc_count": 1,
"Expected_Usage": {
"value": 5
},
"Actual_Usage": {
"value": 3
}
},
{
"key_as_string": "2016-01-12",
"key": 1452556800000,
"doc_count": 1,
"Expected_Usage": {
"value": 43
},
"Actual_Usage": {
"value": 2
}
},
.........,
.........
]
}
}
}
}
}
我想保留插入顺序,因为Elastic Search返回的KEYS已经排序。我还想保持每个键的VALUES顺序。
考虑使用LinkedHashmap和LinkedHashSet。
LinkedHashMap<String, LinkedHashSet<Integer>> LinkedMap =
new LinkedHashMap<String,LinkedHashSet<Integer>>();
LinkedHashSet<Integer> LinkedSet =
new LinkedHashSet<Integer>();
LinkedSet.add(3);
LinkedSet.add(4);
LinkedSet.add(2);
LinkedMap.put("2016/03/11",LinkedSet);
for(Map.Entry m:LinkedMap.entrySet()){
System.out.println("Key is : " + m.getKey() + " Values: " + m.getValue());
}
在内存和性能方面有更好的选择吗?
答案 0 :(得分:2)
有很多选择,主要取决于您将如何使用所获取的数据 - 例如如果您不关心修改数据的调用代码,那么使用公共成员设计结构将导致CPU压力最小。
响应中的最大可能键值为365,每个键只有2个值。
我明白了。我建议删除LinkedHashSet
并编写自定义类来保存这两个整数未装箱(在将int
转换为Integer
并返回时不要浪费CPU):< / p>
public class ExpectedVsActual {
// if you don't care too much of your data integrity
// along other lines of coding, make those public
// and forget about getters
protected int expected;
protected int actual;
public ExpectedVsActual(int exp, int act) {
this.expected=exp;
this.actual=act;
}
public int getExpected() {
return this.expected;
}
public int getActual() {
return this.actual;
}
}
然后
LinkedHashMap<String, ArrayList<ExpectedVsActual>> myMap=...; // etc
当然,如果你不需要搜索键,那么你就不需要地图了。
如果您想要每个键的单独条目,也许最好将每个条目包装为结构:
public class MyEntryRepresentation {
protected String dateStr;
// ArrayList: faster iteration by position
// LinkedList: memory conservative - doesn't allocate more than necessary
protected List<ExpectedVsActual> data;
public MyEntryRepresentation(String date)
this.dateStr=date;
this.data=new ArrayList<ExpectedVsActual>();
}
public void addEntry(int expected, int actual) {
this.data.add(new ExpectedVsActual(expected, actual));
}
public List<ExpectedVsActual> getValues() {
// if you don't care what the caller will do with your List
return this.data;
// If you want to forbid them to modify the returned list
// return Collections.unmodifiableList(this.data);
}
public String getDateStr() {
return this.date;
}
}
然后
LinkedHashMap<String, MyEntryRepresentation> map=... etc;
map.add(entry.getDateStr(), entry);
答案 1 :(得分:1)
linkedhashmap在里面使用一个Entry Array,无论你把一个新值放到地图中,都会创建一个新的Entry,新的Entry可以引用前一个条目。另外,我不建议使用set,因为如果Expected_Usage和Actual_Usage之间有相同的值,则集合中将有一个值。我创建了一个简单的数据结构来解决您的问题,希望这可以提供帮助。
Sending build context to Docker daemon 20 MB
Step 0 : FROM alpine:3.4
---> ad84c222f6a3
Step 1 : RUN apk upgrade --update && apk add libatomic readline readline-dev libxml2 libxml2-dev libxslt libxslt-dev zlib-dev zlib ruby yaml yaml-dev libffi-dev build-base git nodejs ruby-io-console ruby-irb ruby-json ruby-rake make gsl gsl-dev gcc g++ libffi-dev ruby-dev tzdata
---> Using cache
---> b7f66d6f2bd7
Step 2 : RUN gsl-config --cflags
---> Using cache
---> b5acc8868a74
Step 3 : RUN gem install --no-document nmatrix gsl
---> Using cache
---> 2623683a706e
Step 4 : ADD scripts/gsl-test.rb test.rb
---> e4388f952198
Removing intermediate container 743340a3be60
Step 5 : RUN ruby test.rb
---> Running in c53a34ece153
/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': Error relocating /usr/lib/ruby/gems/2.3.0/gems/gsl-2.1.0.1/lib/gsl_native.so: gsl_multifit_fdfsolver_jac: symbol not found - /usr/lib/ruby/gems/2.3.0/gems/gsl-2.1.0.1/lib/gsl_native.so (LoadError)
from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from /usr/lib/ruby/gems/2.3.0/gems/backports-3.6.8/lib/backports/std_lib.rb:9:in `require_with_backports'
from /usr/lib/ruby/gems/2.3.0/gems/gsl-2.1.0.1/lib/gsl.rb:11:in `<top (required)>'
from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:127:in `require'
from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:127:in `rescue in require'
from /usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:40:in `require'
from test.rb:1:in `<main>'
The command '/bin/sh -c ruby test.rb' returned a non-zero code: 1