JSON response Using Volley in a recycler view in Android app - android-recyclerview

I am trying to print a json response response in a recyclerview. my Recyclerview is like a expanded listView. And my json resone is like this:
{"Table1":
[
{"filedate":"Oct 26, 2016"},
{"filedate":"Oct 18, 2016"}
],
"Table2":
[{
"filedate":"Oct 18, 2016",
"file1":"12.txt"
},
{
"filedate":"Oct 26, 2016",
"file1":"acerinvoice.pdf"
}
]}
and I trying to print this json resonse using this code:
private void prepareListData() {
// Volley's json array request object
StringRequest stringRequest = new StringRequest(Request.Method.POST, REGISTER_URL,
new Response.Listener<String>() {
//I think problrm is here
#Override
public void onResponse(String response) {
try {
**JSONObject object = new JSONObject(response);
JSONArray jsonarray = object.getJSONArray("Table1");
JSONArray jsonarray1 = object.getJSONArray("Table2");
for (int i = 0; i < jsonarray.length(); i++) {
try {
JSONObject obj = jsonarray.getJSONObject(i);
String str = obj.optString("filedate").trim();
int lth = jsonarray1.length();
data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.HEADER, str));
for (int j = 0; j < jsonarray1.length(); j++) {
try {
JSONObject obj1 = jsonarray1.getJSONObject(j);
String str1 = obj1.optString("filedate").trim();
data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, str1));
Toast.makeText(getApplicationContext(), str1, Toast.LENGTH_LONG).show();**
//if condition
} catch (JSONException e) {
// Log.e(TAG, "JSON Parsing error: " + e.getMessage());
}
}
// adding movie to movies array
} catch (JSONException e) {
Log.e("gdshfsjkg", "JSON Parsing error: " + e.getMessage());
}
}
Log.d("test", String.valueOf(data));
Toast.makeText(getApplicationContext(), (CharSequence) data, Toast.LENGTH_LONG).show();
} catch (JSONException e) {
e.printStackTrace();
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
recyclerview.setAdapter(new ExpandableListAdapter(data));
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}){
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put(CLIENT, "4");
return params;
}
};
// Adding request to request queue
MyApplication.getInstance().addToRequestQueue(stringRequest);
}
ExpandableListAdapter
public class ExpandableListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public static final int HEADER = 0;
public static final int CHILD = 1;
private List<Item> data;
public ExpandableListAdapter(List<Item> data) {
this.data = data;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int type) {
View view = null;
Context context = parent.getContext();
float dp = context.getResources().getDisplayMetrics().density;
int subItemPaddingLeft = (int) (18 * dp);
int subItemPaddingTopAndBottom = (int) (5 * dp);
switch (type) {
case HEADER:
LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.list_header, parent, false);
ListHeaderViewHolder header = new ListHeaderViewHolder(view);
return header;
case CHILD:
TextView itemTextView = new TextView(context);
itemTextView.setPadding(subItemPaddingLeft, subItemPaddingTopAndBottom, 0, subItemPaddingTopAndBottom);
itemTextView.setTextColor(0x88000000);
itemTextView.setLayoutParams(
new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
return new RecyclerView.ViewHolder(itemTextView) {
};
}
return null;
}
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final Item item = data.get(position);
switch (item.type) {
case HEADER:
final ListHeaderViewHolder itemController = (ListHeaderViewHolder) holder;
itemController.refferalItem = item;
itemController.header_title.setText(item.text);
if (item.invisibleChildren == null) {
itemController.btn_expand_toggle.setImageResource(R.drawable.circle_minus);
} else {
itemController.btn_expand_toggle.setImageResource(R.drawable.circle_plus);
}
itemController.btn_expand_toggle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (item.invisibleChildren == null) {
item.invisibleChildren = new ArrayList<Item>();
int count = 0;
int pos = data.indexOf(itemController.refferalItem);
while (data.size() > pos + 1 && data.get(pos + 1).type == CHILD) {
item.invisibleChildren.add(data.remove(pos + 1));
count++;
}
notifyItemRangeRemoved(pos + 1, count);
itemController.btn_expand_toggle.setImageResource(R.drawable.circle_plus);
} else {
int pos = data.indexOf(itemController.refferalItem);
int index = pos + 1;
for (Item i : item.invisibleChildren) {
data.add(index, i);
index++;
}
notifyItemRangeInserted(pos + 1, index - pos - 1);
itemController.btn_expand_toggle.setImageResource(R.drawable.circle_minus);
item.invisibleChildren = null;
}
}
});
break;
case CHILD:
TextView itemTextView = (TextView) holder.itemView;
itemTextView.setText(data.get(position).text);
break;
}
}
#Override
public int getItemViewType(int position) {
return data.get(position).type;
}
#Override
public int getItemCount() {
return data.size();
}
private static class ListHeaderViewHolder extends RecyclerView.ViewHolder {
public TextView header_title;
public ImageView btn_expand_toggle;
public Item refferalItem;
public ListHeaderViewHolder(View itemView) {
super(itemView);
header_title = (TextView) itemView.findViewById(R.id.header_title);
btn_expand_toggle = (ImageView) itemView.findViewById(R.id.btn_expand_toggle);
}
}
public static class Item {
public int type;
public String text;
public List<Item> invisibleChildren;
public Item() {
}
public Item(int type, String text) {
this.type = type;
this.text = text;
}
}
}
But this code print nothing in my recycler UI.It show only a empty layout.I have also tried to print the response in my log and it prints whole response together.I want to print table1 contents in headers and table2 contents in as child(items) with their respective headers.how to do this?If any other information needed please ask..

You should probably check your response first of everything. As per your requirements you should use HashMap and ArrayList. Follow these following steps:
1.Take a ArrayLsit and store child data of 1st heading and so on with index starting from 0.
2.Store headers in HashMap as key.
ex: HashMap<String,ArrayList<Data>> hm;
hm.put("your first heading string","related arraylist");
Then use ExpandableListView to arrange parent and child items.

please check your json response this is invalid json response first try to validate your json formate after try to decode and add in recycler view.

Check Your Response into Logcat also the Exception. I've tested the Response you've supplied that contains some unnecessary "," that may cause the Exception.

I have solve my problem to just change above code like this..
private void prepareListData() {
// Volley's json array request object
StringRequest stringRequest = new StringRequest(Request.Method.POST, REGISTER_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
JSONObject object = null;
try {
object = new JSONObject(response);
} catch (JSONException e) {
e.printStackTrace();
}
JSONArray jsonarray = null;
JSONArray jsonarray1 = null;
try {
jsonarray = object.getJSONArray("Table1");
jsonarray1 = object.getJSONArray("Table1");
} catch (JSONException e) {
e.printStackTrace();
}
for (int i = 0; i < jsonarray.length(); i++) {
try {
JSONObject obj = jsonarray.getJSONObject(i);
//
String str = obj.optString("filedate").trim();
Log.d("test", str);
data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.HEADER, str));
// Toast.makeText(getApplicationContext(), lth, Toast.LENGTH_LONG).show();
for (int j = 0; j < jsonarray1.length(); j++) {
try {
JSONObject obj1 = jsonarray1.getJSONObject(j);
String str1 = obj1.optString("filedate").trim();
String str3 = obj1.optString("category").trim();
String str2 = obj1.optString("file1").trim();
String str4 = obj1.optString("4").trim();
Toast.makeText(getApplicationContext(), "server data respone", Toast.LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), "test"+str1, Toast.LENGTH_LONG).show();
if (str == str1) {
// data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, str1));
data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, str3));
data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, str2));
}
Toast.makeText(getApplicationContext(), str1, Toast.LENGTH_LONG).show();
//if condition
} catch (JSONException e) {
// Log.e(TAG, "JSON Parsing error: " + e.getMessage());
}
}
// adding movie to movies array
} catch (JSONException e) {
Log.e("gdshfsjkg", "JSON Parsing error: " + e.getMessage());
}
}
Log.d("test", String.valueOf(data));
// notifying list adapter about data changes
// so that it renders the list view with updated data
// adapterheader.notifyDataSetChanged();
recyclerview.setAdapter(new ExpandableListAdapter(data));
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// VolleyLog.d(TAG, "Error: " + error.getMessage());
// hidePDialog();
}
}){
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put(CLIENT, "4");
return params;
}
};
// Adding request to request queue
MyApplication.getInstance().addToRequestQueue(stringRequest);
}

Related

jvm condition and locksupport which is faster?

An experimental example of synchronous call is made. Each thread task waits for a task callback with its own value of + 1. The performance difference between condition and locksupport is compared. The result is unexpected. The two times are the same, but the difference on the flame diagram is very big. Does it mean that the JVM has not optimized locksupport
enter image description here
public class LockerTest {
static int max = 100000;
static boolean usePark = true;
static Map<Long, Long> msg = new ConcurrentHashMap<>();
static ExecutorService producer = Executors.newFixedThreadPool(4);
static ExecutorService consumer = Executors.newFixedThreadPool(16);
static AtomicLong record = new AtomicLong(0);
static CountDownLatch latch = new CountDownLatch(max);
static ReentrantLock lock = new ReentrantLock();
static Condition cond = lock.newCondition();
static Map<Long, Thread> parkMap = new ConcurrentHashMap<>();
static AtomicLong cN = new AtomicLong(0);
public static void main(String[] args) throws InterruptedException {
long start = System.currentTimeMillis();
for (int num = 0; num < max; num++) {
consumer.execute(() -> {
long id = record.incrementAndGet();
msg.put(id, -1L);
call(id);
if (usePark) {
Thread thread = Thread.currentThread();
parkMap.put(id, thread);
while (msg.get(id) == -1) {
cN.incrementAndGet();
LockSupport.park(thread);
}
} else {
lock.lock();
try {
while (msg.get(id) == -1) {
cN.incrementAndGet();
cond.await();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
latch.countDown();
});
}
latch.await();
consumer.shutdown();
producer.shutdown();
System.out.printf("park %s suc %s cost %s cn %s"
, usePark
, msg.entrySet().stream().noneMatch(entry -> entry.getKey() + 1 != entry.getValue())
, System.currentTimeMillis() - start
, cN.get()
);
}
private static void call(long id) {
producer.execute(() -> {
try {
Thread.sleep((id * 13) % 100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (usePark) {
msg.put(id, id + 1);
LockSupport.unpark(parkMap.remove(id));
} else {
lock.lock();
try {
msg.put(id, id + 1);
cond.signalAll();
} finally {
lock.unlock();
}
}
});
}
}

How to put different limit for multi chekbox in recyclerview item

I can choose 2 items from the first group and choose 1 item from the second group.
Now there should be a certain limit for each group and the whole choice as well.
How can I apply it?
#Override
public void onBindViewHolder(#NonNull Holder holder, int position) {
holder.txt_ingredient.setText(ingredients.get(position).getName());
ArrayList<HomeList.Ingredient> sizeArrayList = new ArrayList<>();
sizeArrayList.addAll(ingredients);
for (int i = 0; i < ingredients.get(position).getIngredients().size(); i++) {
indi.add(ingredients.get(position).getIngredients().get(i).getId());
}
for (int i = 0; i < sizeArrayList.get(position).getIngredients().size(); i++) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View rowView = inflater.inflate(R.layout.checkbox_feild, null);
holder.parentLinearSize.addView(rowView, holder.parentLinearSize.getChildCount() - 1);
}
for (int itemPos = 0; itemPos < holder.parentLinearSize.getChildCount(); itemPos++) {
View view1 = holder.parentLinearSize.getChildAt(itemPos);
CheckBox ch = (CheckBox) view1.findViewById(R.id.chkSpe);
TextView cat_value = (TextView) view1.findViewById(R.id.cat_value);
String c = String.valueOf(sizeArrayList.get(position).getIngredients().size());
ch.setText(sizeArrayList.get(position).getIngredients().get(itemPos).getTitle());
ch.setOnCheckedChangeListener(null);
int finalItemPos = itemPos;
ch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int limit = Integer.parseInt(sizeArrayList.get(position).getSelectionLimit());
int globalInc = 0;
if (globalInc == limit && isChecked) {
ch.setChecked(false);
Toast.makeText(context,
"Limit reached!!!", Toast.LENGTH_SHORT).show();
} else if (isChecked) {
globalInc++;
Toast.makeText(context,
globalInc + " checked!",
Toast.LENGTH_SHORT)
.show();
ch.setSelected(isChecked);
if (ch.isChecked()) {
for (int i = 0; i < ingredients.get(position).getIngredients().size(); i++) {
if (i == finalItemPos) {
ingredients.get(position).getIngredients().get(i).setQty("1");
} else
ingredients.get(position).getIngredients().get(i).setQty("0");
}
ingredients.get(position).setIsOpenSection("1");
onItemCheckListener.onItemCheck(sizeArrayList.get(position).getIngredients(), sizeArrayList.get(position));
Toast.makeText(context, sizeArrayList.get(position).getIngredients().get(finalItemPos).getPrice(), Toast.LENGTH_SHORT).show();
onRecycleItemClickListenerExtra.onItemClickListener(holder, position, "selectExtra", sizeArrayList.get(position).getIngredients().get(finalItemPos).getPrice(), "trextra");
} else {
onItemCheckListener.onItemUncheck(sizeArrayList.get(position).getIngredients().get(position));
onRecycleItemClickListenerExtra.onItemClickListener(holder, position, "DeselectExtra", sizeArrayList.get(position).getIngredients().get(finalItemPos).getPrice(), "trextra");
sizeArrayList.get(position).getIngredients().get(finalItemPos).setQty("0");
}
} else if (!isChecked) {
globalInc--;
}
}
});
cat_value.setText(sizeArrayList.get(position).getIngredients().get(itemPos).getPrice());
holder.maximum_amt.setText(sizeArrayList.get(position).getMaximumAmount());
holder.select_limit.setText(sizeArrayList.get(position).getSelectionLimit());
String count = String.valueOf(getItemCount());
holder.total_itm_count.setText(c);
String eql_les_grt = sizeArrayList.get(position).getEqualGraterLess();
if (eql_les_grt.equalsIgnoreCase("1")) {
if (lan.equals("English")) {
String eql_ls_status = "Greater";
holder.euql_grt_les.setText(eql_ls_status);
}
if (lan.equals("Español")) {
String eql_ls_status = "Máximo";
holder.euql_grt_les.setText(eql_ls_status);
}
}
if (eql_les_grt.equalsIgnoreCase("2")) {
if (lan.equals("English")) {
String eql_ls_status = "Exactly";
holder.euql_grt_les.setText(eql_ls_status);
}
if (lan.equals("Español")) {
String eql_ls_status = "solo";
holder.euql_grt_les.setText(eql_ls_status);
}
}
if (eql_les_grt.equalsIgnoreCase("3")) {
if (lan.equals("English")) {
String eql_ls_status = "Less";
holder.euql_grt_les.setText(eql_ls_status);
}
if (lan.equals("Español")) {
String eql_ls_status = "Mínimo";
holder.euql_grt_les.setText(eql_ls_status);
}
}
holder.img_arrow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.rl_details.setVisibility(View.VISIBLE);
holder.img_dwn_arrow.setVisibility(View.VISIBLE);
holder.img_dwn_arrow.setVisibility(View.VISIBLE);
holder.img_arrow.setVisibility(View.GONE);
holder.parentLinearSize.setVisibility(View.VISIBLE);
}
});
holder.img_dwn_arrow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.rl_details.setVisibility(View.GONE);
holder.img_dwn_arrow.setVisibility(View.GONE);
holder.img_dwn_arrow.setVisibility(View.GONE);
holder.img_arrow.setVisibility(View.VISIBLE);
holder.parentLinearSize.setVisibility(View.GONE);
}
});
}

How to move map marker like moving car on road from source to destination

I want to move marker on Google map from source to destination like Uber or Ola and i am working on google map, I am new so Please help me how it is possible ...?
My code is :
public void onMapReady(GoogleMap googleMap) {
GoogleMap gMap = googleMap;
addMarks1(gMap);
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
gMap.setMyLocationEnabled(true);
gMap.getUiSettings().setZoomControlsEnabled(true);
// Turns on 3D buildings
gMap.setBuildingsEnabled(true);
}
private void addMarks1(GoogleMap googleMap) {
googleMap.clear();
// updateRouteOnMAp();
double d_lat=Double.valueOf(rideDetailSessionManager.getColumnFromTaxiDriver(RideDetailSessionManager.KEY_START_LAT));
double d_loing=Double.valueOf(rideDetailSessionManager.getColumnFromTaxiDriver(RideDetailSessionManager.KEY_START_LNG));
fromPosition=new LatLng(d_lat,d_loing);
toPosition=new LatLng(Double.valueOf(rideDetailSessionManager.getColumnFromTaxiDriver(RideDetailSessionManager.KEY_END_LAT)),
Double.valueOf(rideDetailSessionManager.getColumnFromTaxiDriver(RideDetailSessionManager.KEY_END_LNG)));
List<Marker> markersList = new ArrayList<Marker>();
Marker StartLatLon= googleMap.addMarker(new MarkerOptions().position(fromPosition).title("Start Point").icon(BitmapDescriptorFactory.fromResource(R.drawable.red_car_image)));
Marker EndLatLon= googleMap.addMarker(new MarkerOptions().position(toPosition).icon(BitmapDescriptorFactory.fromResource(R.drawable.red_car_image)));
markersList.add(StartLatLon);
markersList.add(EndLatLon);
builder = new LatLngBounds.Builder();
for (Marker m : markersList) {
builder.include(m.getPosition());
}
int padding = 150;
LatLngBounds bounds = builder.build();
cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
googleMap.animateCamera(cu);
traceMe(googleMap);
}
private void traceMe(final GoogleMap googleMap) {
String srcParam;
String destParam;
String startLat=rideDetailSessionManager.getColumnFromTaxiDriver(RideDetailSessionManager.KEY_START_LAT);
String startLng=rideDetailSessionManager.getColumnFromTaxiDriver(RideDetailSessionManager.KEY_START_LNG);
GPSTracker gpsTracker=new GPSTracker(getActivity());
srcParam = startLat + "," + startLng;
destParam = gpsTracker.getLatitude() + "," + gpsTracker.getLongitude();
Log.d("drop lat pp2", ":" + destParam);
String modes[] = {"driving", "walking", "bicycling", "transit"};
String url = "https://maps.googleapis.com/maps/api/directions/json?origin=" + srcParam + "&destination=" + destParam + "&sensor=false&units=metric&mode=driving";
StringRequest jsonObjectRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("dkp lat long", ":" + response);
JSONObject jsonObject=null;
try {
jsonObject=new JSONObject(response);
} catch (JSONException e) {
e.printStackTrace();
}
MapDirectionsParser parser = new MapDirectionsParser();
List<List<HashMap<String, String>>> routes = parser.parse(jsonObject);
for (int i = 0; i < routes.size(); i++) {
points = new ArrayList<LatLng>();
List<HashMap<String, String>> path = routes.get(i);
Log.d("dkp lat long", ":" + path);
for (int j = 0; j < path.size(); j++) {
HashMap<String, String> point = path.get(j);
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
}
}
Log.d("dkp points lat long", ":" + points);
drawPoints(points, googleMap);
String str_dist=parser.distance();
//String str_dur=parser.duration();
if (!str_dist.equals("null"))
{
distance= Integer.parseInt(str_dist);
//estimate_distance= (distance/100)+50;
//rideEstimateDistance.setText((estimate_distance-50)+"-"+estimate_distance);
Log.d("dkp kkk distance", ":" + distance);
}
/*if (!str_dur.equals("null"))
{
int duration=Integer.parseInt(parser.duration());
estimate_duration= duration/60;
ideEstimateDistance.setText((estimate_distance-50)+"-"+estimate_distance);
Log.d("dkp kkk duration", ":" + duration);
}*/
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
if (error instanceof TimeoutError || error instanceof NoConnectionError) {
Log.d("error ocurred", "TimeoutError");
//Toast.makeText(getActivity(), "TimeoutError", Toast.LENGTH_LONG).show();
} else if (error instanceof AuthFailureError) {
Log.d("error ocurred", "AuthFailureError");
//Toast.makeText(getActivity(), "AuthFailureError", Toast.LENGTH_LONG).show();
} else if (error instanceof ServerError) {
Log.d("error ocurred", "ServerError");
// emailEdt.requestFocus();
// Toast.makeText(getActivity(), "Please enter valid email or password", Toast.LENGTH_LONG).show();
// Toast.makeText(getActivity(), "ServerError", Toast.LENGTH_LONG).show();
} else if (error instanceof NetworkError) {
Log.d("error ocurred", "NetworkError");
//Toast.makeText(getActivity(), "NetworkError", Toast.LENGTH_LONG).show();
} else if (error instanceof ParseError) {
Log.d("error ocurred", "ParseError");
//Toast.makeText(getActivity(), "ParseError", Toast.LENGTH_LONG).show();
}
}
});
// MyApplication.getInstance().addToRequestQueue(jsonObjectRequest, "jreq");
RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
requestQueue.add(jsonObjectRequest);
}
private void drawPoints(ArrayList<LatLng> points, GoogleMap mMaps) {
if (points == null) {
return;
}
traceOfMe = points;
PolylineOptions polylineOpt = new PolylineOptions();
for (LatLng latlng : traceOfMe) {
polylineOpt.add(latlng);
}
polylineOpt.color(Color.BLUE);
if (mPolyline != null) {
mPolyline.remove();
mPolyline = null;
}
if (mMaps != null) {
mPolyline = mMaps.addPolyline(polylineOpt);
} else {
}
if (mPolyline != null)
mPolyline.setWidth(7);
}
You will have to remove the marker from the map using googleMap.clear() and redraw it again in the new location.

How to deserialize a JSON object to a binary tree by using Jackson

From the previous question How to deserialize a JSON array to a singly linked list , I learned how to deserialize a JSON array to a singly linked list.
Now I want to deserialize a JSON object to a binary tree in Java.
The definition of the binary tree node is as the following:
public class BinaryTreeNode<E> {
public E value;
public BinaryTreeNode left;
public BinaryTreeNode right;
public BinaryTreeNode(final E value) {
this.value = value;
}
}
How to deserialize a JSON string such as:
{
"value": 2,
"left": {
"value": 1,
"left": null,
"right": null
},
"right": {
"value": 10,
"left": {
"value": 5,
"left": null,
"right": null
},
"right": null
}
}
to a binary tree?
2
/ \
1 10
/
5
Here is the unit test code:
#Test public void binaryTreeNodeTest() throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
final ArrayList<Integer> intArray = objectMapper.readValue("[1,2,3,4,5]",
new TypeReference<ArrayList<Integer>>() {});
System.out.println(intArray);
/* How to achieve this?
2
/ \
1 10
/
5
{
"value": 2,
"left": {
"value": 1,
"left": null,
"right": null
},
"right": {
"value": 10,
"left": {
"value": 5,
"left": null,
"right": null
},
"right": null
}
}
*/
final String jsonStr = "{\n"
+ " \"value\": 2,\n"
+ " \"left\": {\n"
+ " \"value\": 1,\n"
+ " \"left\": null,\n"
+ " \"right\": null\n"
+ " },\n" + " \"right\": {\n"
+ " \"value\": 10,\n"
+ " \"left\": {\n"
+ " \"value\": 5,\n"
+ " \"left\": null,\n"
+ " \"right\": null\n"
+ " },\n"
+ " \"right\": null\n"
+ " }\n"
+ "}";
System.out.println(jsonStr);
final BinaryTreeNode<Integer> intTree = objectMapper.readValue(jsonStr,
new TypeReference<BinaryTreeNode<Integer>>() {});
System.out.println(intTree);
}
In other word, I want the BinaryTreeNode to be a first-class citizen the same as ArrayList, which can be used in all kinds of combinations, such as HashSet<BinaryTreeNode<Integer>>, BinaryTreeNode<HashMap<String, Integer>>, etc.
The solution is quite simple, since JSON can express tree naturally, Jackson can deal with recursive tree directly. Just annotate a constructor with JsonCreator:
public static class BinaryTreeNode<E>
{
public E value;
public BinaryTreeNode left;
public BinaryTreeNode right;
#JsonCreator
public BinaryTreeNode(#JsonProperty("value") final E value) {
this.value = value;
}
}
Let's write a unite test to try it:
package me.soulmachine.customized_collection;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
public class BinaryTreeNodeTest {
public static class BinaryTreeNode<E> {
public E value;
public BinaryTreeNode left;
public BinaryTreeNode right;
#JsonCreator
public BinaryTreeNode(#JsonProperty("value") final E value) {
this.value = value;
}
ArrayList<E> preOrder() {
final ArrayList<E> result = new ArrayList<>();
if (this.value == null) {
return result;
}
preOrder(this, result);
return result;
}
private static <E> void preOrder(BinaryTreeNode<E> root, ArrayList<E> result) {
if (root == null)
return;
result.add(root.value);
if (root.left != null)
preOrder(root.left, result);
if (root.right != null)
preOrder(root.right, result);
}
}
#Test public void binaryTreeNodeTest() throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
/*
2
/ \
1 10
/
5
*/
final String jsonStr = "{\n"
+ " \"value\": 2,\n"
+ " \"left\": {\n"
+ " \"value\": 1,\n"
+ " \"left\": null,\n"
+ " \"right\": null\n"
+ " },\n" + " \"right\": {\n"
+ " \"value\": 10,\n"
+ " \"left\": {\n"
+ " \"value\": 5,\n"
+ " \"left\": null,\n"
+ " \"right\": null\n"
+ " },\n"
+ " \"right\": null\n"
+ " }\n"
+ "}";
System.out.println(jsonStr);
final BinaryTreeNode<Integer> intTree = objectMapper.readValue(jsonStr,
new TypeReference<BinaryTreeNode<Integer>>() {});
final List<Integer> listExpected = Arrays.asList(2, 1, 10, 5);
assertEquals(listExpected, intTree.preOrder());
}
}
A compact serialization format
Well, there is a little problem here, the JSON string above is very verbose. Let's use another kind of serialization format, i.e., serialize a binary tree in level order traversal. For example, the binary tree above can be serialized as the following JSON string:
[2,1,10,null,null,5]
Now how to deserialize this JSON string to a binary tree?
The idea is very similar to my previous article, Deserialize a JSON Array to a Singly Linked List. Just make the BinaryTreeNode implement java.util.list, pretend that it's a list, write our own deserialization code so that Jackson can treat a binary tree as a list.
The complete code of BinaryTreeNode is as the following:
package me.soulmachine.customized_collection;
import java.util.*;
public class BinaryTreeNode<E> extends AbstractSequentialList<E>
implements Cloneable, java.io.Serializable {
public E value;
public BinaryTreeNode<E> left;
public BinaryTreeNode<E> right;
/** has a left child, but it's a null node. */
private transient boolean leftIsNull;
/** has a right child, but it's a null node. */
private transient boolean rightIsNull;
/**
* Constructs an empty binary tree.
*/
public BinaryTreeNode() {
value = null;
left = null;
right = null;
}
/**
* Constructs an binary tree with one element.
*/
public BinaryTreeNode(final E value) {
if (value == null) throw new IllegalArgumentException("null value");
this.value = value;
left = null;
right = null;
}
/**
* Constructs a binary tree containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
*
* #param c the collection whose elements are to be placed into this binary tree
* #throws NullPointerException if the specified collection is null
*/
public BinaryTreeNode(Collection<? extends E> c) {
this();
addAll(c);
}
/**
* #inheritDoc
*
* <p>Note: null in the middle counts, so that each father in the binary tree has a
* one-to-one mapping with the JSON array.</p>
*/
public int size() {
if (value == null) return 0;
Queue<BinaryTreeNode<E>> queue = new LinkedList<>();
queue.add(this);
int count = 0;
while (!queue.isEmpty()) {
final BinaryTreeNode<E> node = queue.remove();
++count;
if (node.left != null) {
queue.add(node.left);
} else {
if (node.leftIsNull) ++count;
}
if (node.right != null) {
queue.add(node.right);
} else {
if (node.rightIsNull) ++count;
}
}
return count;
}
/**
* Tells if the argument is the index of a valid position for an
* iterator or an add operation.
*/
private boolean isPositionIndex(int index) {
return index >= 0 && index <= size();
}
/**
* Constructs an IndexOutOfBoundsException detail message.
* Of the many possible refactorings of the error handling code,
* this "outlining" performs best with both server and client VMs.
*/
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+ size();
}
private void checkPositionIndex(int index) {
if (!isPositionIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private class NodeAndFather {
private BinaryTreeNode<E> node;
private BinaryTreeNode<E> father;
private boolean isRight; // the father is the right child of the father
private NodeAndFather(BinaryTreeNode<E> node, BinaryTreeNode<E> father, boolean isRight) {
this.node = node;
this.father = father;
this.isRight = isRight;
}
}
/**
* Returns the (may be null) Node at the specified element index.
*/
NodeAndFather node(int index) {
checkPositionIndex(index);
if (value == null) return null;
Queue<NodeAndFather> queue = new LinkedList<>();
queue.add(new NodeAndFather(this, null, false));
for (int i = 0; !queue.isEmpty(); ++i) {
final NodeAndFather nodeAndFather = queue.remove();
if ( i == index) {
return nodeAndFather;
}
if (nodeAndFather.node != null) {
queue.add(new NodeAndFather(nodeAndFather.node.left, nodeAndFather.node, false));
queue.add(new NodeAndFather(nodeAndFather.node.right, nodeAndFather.node, true));
}
}
throw new IllegalArgumentException("Illegal index: " + index);
}
/**
* #inheritDoc
*/
public ListIterator<E> listIterator(int index) {
checkPositionIndex(index);
return new ListItr(index);
}
private class ListItr implements ListIterator<E> {
private NodeAndFather next;
private int nextIndex;
private int expectedModCount = modCount;
ListItr(int index) {
assert isPositionIndex(index);
next = node(index);
nextIndex = index;
}
public boolean hasNext() {
final BinaryTreeNode<E> cur = next.node;
return cur != null || (next.father.leftIsNull || next.father.rightIsNull);
}
//O(n)
public E next() {
checkForComodification();
if (!hasNext())
throw new NoSuchElementException();
final E result = next.node != null ? next.node.value : null;
next = node(nextIndex+1);
nextIndex++;
return result;
}
public boolean hasPrevious() {
throw new UnsupportedOperationException();
}
public E previous() {
throw new UnsupportedOperationException();
}
public int nextIndex() {
throw new UnsupportedOperationException();
}
public int previousIndex() {
throw new UnsupportedOperationException();
}
public void remove() {
throw new UnsupportedOperationException();
}
public void set(E e) {
throw new UnsupportedOperationException();
}
public void add(E e) { // always append at the tail
checkForComodification();
if (next == null) { // empty list
BinaryTreeNode.this.value = e;
BinaryTreeNode.this.left = null;
BinaryTreeNode.this.right = null;
} else {
final BinaryTreeNode<E> newNode = e != null ? new BinaryTreeNode<>(e) : null;
if (next.father == null) { // root
BinaryTreeNode<E> cur = next.node;
cur.left = newNode;
assert cur.right == null;
throw new UnsupportedOperationException();
} else {
if (next.isRight) {
if (next.father.right != null) throw new IllegalStateException();
next.father.right = newNode;
if (newNode == null) {
next.father.rightIsNull = true;
}
} else {
if (next.father.left != null) throw new IllegalStateException();
next.father.left = newNode;
if (newNode == null) {
next.father.leftIsNull = true;
}
}
}
}
modCount++;
expectedModCount++;
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
// the following functions are just for unit tests.
ArrayList<E> preOrder() {
final ArrayList<E> result = new ArrayList<>();
if (this.value == null) {
return result;
}
preOrder(this, result);
return result;
}
private static <E> void preOrder(BinaryTreeNode<E> root, ArrayList<E> result) {
if (root == null)
return;
result.add(root.value);
if (root.left != null)
preOrder(root.left, result);
if (root.right != null)
preOrder(root.right, result);
}
ArrayList<E> inOrder() {
final ArrayList<E> result = new ArrayList<>();
if (this.value == null) {
return result;
}
inOrder(this, result);
return result;
}
private static <E> void inOrder(BinaryTreeNode<E> root, ArrayList<E> result) {
if (root == null)
return;
if (root.left != null)
inOrder(root.left, result);
result.add(root.value);
if (root.right != null)
inOrder(root.right, result);
}
ArrayList<E> postOrder() {
final ArrayList<E> result = new ArrayList<>();
if (this.value == null) {
return result;
}
postOrder(this, result);
return result;
}
private static <E> void postOrder(BinaryTreeNode<E> root, ArrayList<E> result) {
if (root == null)
return;
if (root.left != null)
postOrder(root.left, result);
if (root.right != null)
postOrder(root.right, result);
result.add(root.value);
}
ArrayList<E> levelOrder() {
final ArrayList<E> result = new ArrayList<>();
if (this.value == null) {
return result;
}
Queue<BinaryTreeNode<E>> queue = new LinkedList<>();
queue.add(this);
while (!queue.isEmpty()) {
final BinaryTreeNode<E> node = queue.remove();
result.add(node.value);
if (node.left != null)
queue.add(node.left);
if (node.right != null)
queue.add(node.right);
}
return result;
}
}
Then comes with the unit tests:
java
package me.soulmachine.customized_collection;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
public class BinaryTreeNodeTest
{
#Test public void deserializeTest() throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
final List<Integer> intList = Arrays.asList(2,1,10,null,null,5);
/*
2
/ \
1 10
/
5
*/
// TODO: the time complexity is O(n^2)
final BinaryTreeNode<Integer> intTree = objectMapper.readValue("[2,1,10,null,null,5]",
new TypeReference<BinaryTreeNode<Integer>>() {});
assertEquals(intList, intTree);
assertEquals(Arrays.asList(2, 1, 10, 5), intTree.levelOrder());
assertEquals(Arrays.asList(2, 1, 10, 5), intTree.preOrder());
assertEquals(Arrays.asList(1, 2, 5, 10), intTree.inOrder());
assertEquals(Arrays.asList(1, 5, 10, 2), intTree.postOrder());
}
}
This article is inspired by Tatu Saloranta from this post, special thanks to him!
Here is my original blog, Deserialize a JSON String to a Binary Tree

With Lucene 4.3.1, How to get all terms which occur in sub-range of all docs

Suppose a lucene index with fields : date, content.
I want to get all terms value and frequency of docs whose date is yesterday. date field is keyword field. content field is analyzed and indexed.
Pls help me with sample code.
My solution source is as follow ...
/**
*
*
* #param reader
* #param fromDateTime
* - yyyymmddhhmmss
* #param toDateTime
* - yyyymmddhhmmss
* #return
*/
static public String top10(IndexSearcher searcher, String fromDateTime,
String toDateTime) {
String top10Query = "";
try {
Query query = new TermRangeQuery("tweetDate", new BytesRef(
fromDateTime), new BytesRef(toDateTime), true, false);
final BitSet bits = new BitSet(searcher.getIndexReader().maxDoc());
searcher.search(query, new Collector() {
private int docBase;
#Override
public void setScorer(Scorer scorer) throws IOException {
}
#Override
public void setNextReader(AtomicReaderContext context)
throws IOException {
this.docBase = context.docBase;
}
#Override
public void collect(int doc) throws IOException {
bits.set(doc + docBase);
}
#Override
public boolean acceptsDocsOutOfOrder() {
return false;
}
});
//
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_43,
EnglishStopWords.getEnglishStopWords());
//
HashMap<String, Long> wordFrequency = new HashMap<>();
for (int wx = 0; wx < bits.length(); ++wx) {
if (bits.get(wx)) {
Document wd = searcher.doc(wx);
//
TokenStream tokenStream = analyzer.tokenStream("temp",
new StringReader(wd.get("content")));
// OffsetAttribute offsetAttribute = tokenStream
// .addAttribute(OffsetAttribute.class);
CharTermAttribute charTermAttribute = tokenStream
.addAttribute(CharTermAttribute.class);
tokenStream.reset();
while (tokenStream.incrementToken()) {
// int startOffset = offsetAttribute.startOffset();
// int endOffset = offsetAttribute.endOffset();
String term = charTermAttribute.toString();
if (term.length() < 2)
continue;
Long wl;
if ((wl = wordFrequency.get(term)) == null)
wordFrequency.put(term, 1L);
else {
wl += 1;
wordFrequency.put(term, wl);
}
}
tokenStream.end();
tokenStream.close();
}
}
analyzer.close();
// sort
List<String> occurterm = new ArrayList<String>();
for (String ws : wordFrequency.keySet()) {
occurterm.add(String.format("%06d\t%s", wordFrequency.get(ws),
ws));
}
Collections.sort(occurterm, Collections.reverseOrder());
// make query string by top 10 words
int topCount = 10;
for (String ws : occurterm) {
if (topCount-- == 0)
break;
String[] tks = ws.split("\\t");
top10Query += tks[1] + " ";
}
top10Query.trim();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
// return top10 word string
return top10Query;
}