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();
}
}
});
}
}
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);
}
});
}
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.
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
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;
}