LEVENSHTEIN_DISTANCE doesn't ignore order by comparing of lists - list

P.P.S. Ok, I founded hier Javers Comparing Lists following comment
There is no concept of move in JaVers list comparison algorithms. After a move there will be two changes reported: ValueAdded and ValueRemoved, just like you have mentioned.
But how then I can recognize, that the list actually has not been changed?
P.S. Even if I get #Entities and #Id to ZasFish, ZasCatchZone and ZasCatchArea I still get
Diff:
1. NewObject{globalId:'my.javers.comparator.ZasFish/2'}
2. ObjectRemoved{globalId:'my.javers.comparator.ZasFish/1'}
I'm trying to compare lists of custom objects. I set LEVENSHTEIN_DISTANCE and created custom comparators. The only difference between objects is the order of values in the lists. I would expect "no changes", but I got ListChange. The result and example is below. What am I doing wrong?
Many thanks and regards,
Andrej
Diff:
1. ListChange{globalId:'my.javers.comparator.ZasFish/', property:'zones', containerChanges:[(2).'my.javers.comparator.ZasCatchZone#7a9273a8'>>'my.javers.comparator.ZasCatchZone#26a7b76d', (1).'my.javers.comparator.ZasCatchZone#4abdb505'>>'my.javers.comparator.ZasCatchZone#7ce6a65d', (0).'my.javers.comparator.ZasCatchZone#1500955a'>>'my.javers.comparator.ZasCatchZone#e874448']}
2. ListChange{globalId:'my.javers.comparator.ZasFish/', property:'areas', containerChanges:[(2).'my.javers.comparator.ZasCatchArea#7113b13f'>>'my.javers.comparator.ZasCatchArea#45820e51', (1).'my.javers.comparator.ZasCatchArea#42d8062c'>>'my.javers.comparator.ZasCatchArea#6043cd28', (0).'my.javers.comparator.ZasCatchArea#cb51256'>>'my.javers.comparator.ZasCatchArea#59906517']}
package my.javers.comparator;
public class ZasCatchArea {
String catchArea;
public String getCatchArea() {
return catchArea;
}
public void setCatchArea(String catchArea) {
this.catchArea = catchArea;
}
}
public class ZasCatchZone {
String catchZone;
public String getCatchZone() {
return catchZone;
}
public void setCatchZone(String catchZone) {
this.catchZone = catchZone;
}
}
public class ZasFish {
String fischName;
List<ZasCatchZone> zones = new ArrayList<ZasCatchZone>();
List<ZasCatchArea> areas = new ArrayList<ZasCatchArea>();
public String getFischName() {
return fischName;
}
public void setFischName(String fischName) {
this.fischName = fischName;
}
public List<ZasCatchZone> getZones() {
return zones;
}
public void setZones(List<ZasCatchZone> zones) {
this.zones = zones;
}
public List<ZasCatchArea> getAreas() {
return areas;
}
public void setAreas(List<ZasCatchArea> areas) {
this.areas = areas;
}
}
public class ZasCatchAreaComparator implements
CustomPropertyComparator<ZasCatchArea, ValueChange> {
public ValueChange compare(ZasCatchArea left, ZasCatchArea right,
GlobalId affectedCdoId, Property propertyName) {
if (left.getCatchArea().equals(right.getCatchArea()))
return null;
return new ValueChange(affectedCdoId, propertyName.getName(), left, right);
}
}
public class ZasCatchZoneComparator implements
CustomPropertyComparator<ZasCatchZone, ValueChange> {
public ValueChange compare(ZasCatchZone left, ZasCatchZone right,
GlobalId affectedCdoId, Property propertyName) {
if (left.getCatchZone().equals(right.getCatchZone()))
return null;
return new ValueChange(affectedCdoId, propertyName.getName(), left, right);
}
}
public class MyComparator {
public static void main(String[] args) {
Javers javers = JaversBuilder.javers()
.registerCustomComparator(new ZasCatchAreaComparator(), ZasCatchArea.class)
.registerCustomComparator(new ZasCatchZoneComparator(), ZasCatchZone.class)
.withListCompareAlgorithm(ListCompareAlgorithm.LEVENSHTEIN_DISTANCE).build();
ZasFish fisch1 = new ZasFish();
ZasFish fisch2 = new ZasFish();
ZasCatchZone z1 = new ZasCatchZone();
z1.setCatchZone("zone1");
ZasCatchZone z2 = new ZasCatchZone();
z2.setCatchZone("zone2");
ZasCatchZone z3 = new ZasCatchZone();
z3.setCatchZone("zone3");
fisch1.getZones().add(z1);
fisch1.getZones().add(z2);
fisch1.getZones().add(z3);
ZasCatchArea a1 = new ZasCatchArea();
a1.setCatchArea("area1");
ZasCatchArea a2 = new ZasCatchArea();
a2.setCatchArea("area2");
ZasCatchArea a3 = new ZasCatchArea();
a3.setCatchArea("area3");
fisch1.getAreas().add(a1);
fisch1.getAreas().add(a2);
fisch1.getAreas().add(a3);
ZasCatchZone z4 = new ZasCatchZone();
z4.setCatchZone("zone3");
ZasCatchZone z5 = new ZasCatchZone();
z5.setCatchZone("zone2");
ZasCatchZone z6 = new ZasCatchZone();
z6.setCatchZone("zone1");
fisch2.getZones().add(z4);
fisch2.getZones().add(z5);
fisch2.getZones().add(z6);
ZasCatchArea a4 = new ZasCatchArea();
a4.setCatchArea("area3");
ZasCatchArea a5 = new ZasCatchArea();
a5.setCatchArea("area1");
ZasCatchArea a6 = new ZasCatchArea();
a6.setCatchArea("area2");
fisch2.getAreas().add(a4);
fisch2.getAreas().add(a5);
fisch2.getAreas().add(a6);
Diff diff = javers.compare(fisch1, fisch2);
System.out.println(diff);
}
}

I think I founded a solution for my issue. If I register values and value objects like this
final Javers javers = JaversBuilder.javers()
.registerCustomComparator(new ZasCatchAreaComparator(), ZasCatchArea.class)
.registerCustomComparator(new ZasCatchZoneComparator(), ZasCatchZone.class)
.registerValue(ZasCatchArea.class).registerValue(ZasCatchZone.class).registerValueObject(ZasFish.class)
.withListCompareAlgorithm(ListCompareAlgorithm.LEVENSHTEIN_DISTANCE).build();
Then I get as diff
1. ListChange{globalId:'my.javers.comparator.ZasFish/', property:'zones', containerChanges:[(2).'my.javers.comparator.ZasCatchZone#19bef4e5'>>'my.javers.comparator.ZasCatchZone#3f1abed', (1).'my.javers.comparator.ZasCatchZone#e37f307f'>>'my.javers.comparator.ZasCatchZone#2ad1e8a5', (0).'my.javers.comparator.ZasCatchZone#2ccd3209'>>'my.javers.comparator.ZasCatchZone#c0fd1f30']}
2. ListChange{globalId:'my.javers.comparator.ZasFish/', property:'areas', containerChanges:[(2).'my.javers.comparator.ZasCatchArea#48115f4e'>>'my.javers.comparator.ZasCatchArea#a1efa37', (1).'my.javers.comparator.ZasCatchArea#c08d9768'>>'my.javers.comparator.ZasCatchArea#d65a5a2', (0).'my.javers.comparator.ZasCatchArea#bb03583'>>'my.javers.comparator.ZasCatchArea#1ebaaab0']}
And as I don't have any ValueChange in this case I can ignore ListChange -> my Lists are identical.

Related

MapReduce for Loading TSV

I am trying to load data into Cloud Bigtable using mapreduce job such that the values of the first column are set to hbase row key.Here is my code and a sample TSV file.
1011 v1 v2 v3 v4
1012 c1 c2 c3 c4
1013 k1 k2 k3 k4
1014 s1 s2 s3 s4
1015 r1 r3 r2 r4
1016 p1 p2 p7 p9
Here is my code sample :-
public static class TokenizerMapper extends
Mapper<Text, Text, Text,Text> {
#Override
public void map(Text key, Text value, Context context) throws IOException,
InterruptedException {
String fields[] = null;
CSVParser csvParser = new CSVParser('\t');
fields = csvParser.parseLine(value.toString());
LOG.info(fields[0]);
context.write(new Text(fields[0]), value);
}
}
public static class MyTableReducer extends
TableReducer<Text, Text, Text> {
#Override
public void reduce(Text key, Iterable<Text> values, Context context)
throws IOException, InterruptedException {
String[] fields = null;
CSVParser csvParser = new CSVParser('\t');
try {
for(Text value: values) {
fields = csvParser.parseLine(value.toString());
for (int i = 1; i < fields.length; ++i) {
Put put = new Put(Bytes.toBytes(fields[0]));
put.addColumn(COLUMN_FAMILY, Bytes.toBytes(cols[i]), Bytes.toBytes(fields[i]));
context.write(key, put);
}
}
} catch (Exception ex) {
context.getCounter("HBaseKVMapper", "PARSE_ERRORS").increment(1);
return;
}
}
}
public static void main(String[] args) throws Exception {
Configuration conf = HBaseConfiguration.create();
conf.set("mapreduce.input.keyvaluelinerecordreader.key.value.separator", "\t");
Job job = Job.getInstance(conf, "BigTableLoader");
job.setInputFormatClass(KeyValueTextInputFormat.class);
KeyValueTextInputFormat.addInputPath(job,new Path(args[0]));
TableName tableName = TableName.valueOf(args[1]);
job.setJarByClass(BigtableLoader.class);
job.setMapperClass(TokenizerMapper.class);
job.setMapOutputValueClass(Text.class);
job.setMapOutputKeyClass(Text.class);
TableMapReduceUtil.initTableReducerJob(tableName.getNameAsString(), MyTableReducer.class, job);
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
The problem I am getting is that instead of the first column, the second column has been set as the key in the table, and also the first column is ignored completely i.e. it doesn't exist in the table.
Is there that something I am missing??

OSMdroid bounds marker

////OSMdroid centered on the markers////
I add markers, I need to map the maximum increases or decreases in such a way that all markers were visible
my code:
public class mapcode extends Activity {
globalvar appState;
int stats=0;
private MapView mapView;
private IMapController mapController;
private SimpleLocationOverlay mMyLocationOverlay;
private ScaleBarOverlay mScaleBarOverlay;
ItemizedIconOverlay<OverlayItem> currentLocationOverlay;
DefaultResourceProxyImpl resourceProxy;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.map);
appState = ((globalvar) getApplicationContext());
mapView = (MapView) this.findViewById(R.id.mapview);
mapView.setTileSource(TileSourceFactory.MAPNIK);
// mapView.setBuiltInZoomControls(true); //кнопка ZOOM +-
mapView.setMultiTouchControls(true);
mapController = this.mapView.getController();
mapController.setZoom(2);
this.mMyLocationOverlay = new SimpleLocationOverlay(this);
this.mapView.getOverlays().add(mMyLocationOverlay);
this.mScaleBarOverlay = new ScaleBarOverlay(this);
this.mapView.getOverlays().add(mScaleBarOverlay);
// this.mapView
/////////////////
resourceProxy = new DefaultResourceProxyImpl(getApplicationContext());
GeoPoint currentLocation = new GeoPoint(55.860863,37.115046);
GeoPoint currentLocation2 = new GeoPoint(63.557413,-156.102119);
OverlayItem myLocationOverlayItem = new OverlayItem("Here", "Current Position", currentLocation);
Drawable myCurrentLocationMarker = this.getResources().getDrawable(R.drawable.a);
myLocationOverlayItem.setMarker(myCurrentLocationMarker);
// myLocationOverlayItem.setMarkerHotspot(HotspotPlace.CENTER); //no working/
final ArrayList<OverlayItem> items = new ArrayList<OverlayItem>();
items.add(myLocationOverlayItem);
myLocationOverlayItem = new OverlayItem("Here", "Current Position", currentLocation2);
myCurrentLocationMarker = this.getResources().getDrawable(R.drawable.a);
myLocationOverlayItem.setMarker(myCurrentLocationMarker);
// myLocationOverlayItem.setMarkerHotspot(HotspotPlace.CENTER); // no working
items.add(myLocationOverlayItem);
currentLocationOverlay = new ItemizedIconOverlay<OverlayItem>(items,
new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
public boolean onItemSingleTapUp(final int index, final OverlayItem item) {
return true;
}
public boolean onItemLongPress(final int index, final OverlayItem item) {
return true;
}
}, resourceProxy);
this.mapView.getOverlays().add(this.currentLocationOverlay);
}
I added two markers, but only one is visible:
and I need to osmdroid is centered and immediately showed both marker
I think you want something like this:
int minLat = Integer.MAX_VALUE;
int maxLat = Integer.MIN_VALUE;
int minLong = Integer.MAX_VALUE;
int maxLong = Integer.MIN_VALUE;
ArrayList<OverlayItem> items = new ArrayList<OverlayItem>();
for (OverlayItem item : items) {
GeoPoint point = item.getPoint();
if (point.getLatitudeE6() < minLat)
minLat = point.getLatitudeE6();
if (point.getLatitudeE6() > maxLat)
maxLat = point.getLatitudeE6();
if (point.getLongitudeE6() < minLong)
minLong = point.getLongitudeE6();
if (point.getLongitudeE6() > maxLong)
maxLong = point.getLongitudeE6();
}
BoundingBoxE6 boundingBox = new BoundingBoxE6(maxLat, maxLong, minLat, minLong);
mMapView.zoomToBoundingBox(boundingBox);
You can calculate boundingBox by BoundingBox.fromGeoPoints(geoPoints)
fun zoomToBounds(points: List<LatLng>) {
val geoPoints = points.map { GeoPoint(it.latitude, it.longitude) }
val boundingBox = BoundingBox.fromGeoPoints(geoPoints)
mapView.zoomToBoundingBox(boundingBox, true)
}
It is also possible to have some paddings by using zoomtoBoundingBox overloaded method and setting the pBorderSizeInPixels parameter
public double zoomToBoundingBox(
final BoundingBox pBoundingBox,
final boolean pAnimated,
final int pBorderSizeInPixels,
final double pMaximumZoom,
final Long pAnimationSpeed
)

List and Map in java programing

I need to convert:
List<Map>([{1,2},{2,3}])
To:
List<List>([[1,2],[2,3]])
Can anyone help me with example for this ...
Thanks
I would suggest making a list of specific objects instead of a raw list that the get(0) returns the key and get(1) the value as follows:
List<List<Pair>> convert(List<Map<Integer,Integer> mapList){
List<List<Pair>> listOfList = new ArrayList<List<Pair>>();
for(Map<Integer,Integer> map:mapList){
List<Pair> list = new ArrayList<Pair>();
for(Entry<Integer,Integer> e:map.entrySet()){
list.add(Pair(e.getKey(),e.getValue());
}
listOfList.add(list);
}
return listOfList;
}
class Pair{
Integer first;
Integer second;
//constructor
}
You can try the following Code:
import java.util.*;
class ListOfMapToListOfList
{
public static List<List> toList(List<Map<Integer,Integer>> lList)//method to convert List<Map> to List<List>
{
List<List> list = new ArrayList<List>();
for (int i = 0 ; i < lList.size() ; i++)
{
Map<Integer,Integer> map = lList.get(i);
List<Integer> aList = new ArrayList<Integer>();
Set<Integer> keySet = map.keySet();
for (Integer key : keySet)
{
aList.add(key);
aList.add(map.get(key));
}
list.add(aList);
}
return list;
}
public static void main(String[] args) //main body
{
List<Map<Integer,Integer>> list1 = new ArrayList<Map<Integer,Integer>>();
Map<Integer,Integer> map1 = new HashMap<Integer,Integer>();
map1.put(1,2);
Map<Integer,Integer> map2 = new HashMap<Integer,Integer>();
map2.put(1,2);
list1.add(map1);list1.add(map2);
System.out.println(list1);
System.out.println(toList(list1));//Conversion is done here..and out put is shown.
}
}

JavaFX - bind property to properties of every element in observable Collection

Does exist any method which bind BooleanProperty to conjunction of every element in ObservableList?
ObservableList<BooleanProperty> list;
list = FXCollections.observableList(new ArrayList<BooleanProperty>));
BooleanProperty emptyProperty = new SimpleBooleanProperty();
emptyProperty.bind(Bindings.conunction(list));`
Is there such a method as:
static BooleanBinding conjunction(ObservableList<BooleanProperty> op)
There is no conjunction api defined in the JavaFX 2.2 platform.
You could create a ConjunctionBooleanBinding (aka AllTrueBinding) by subclassing BooleanBinding.
Accept the ObservableList in the constructor of your new class, and use the low level binding api in an overridden computeValue method to set the binding value based upon logically anding together all of the boolean values in the list.
Here is a sample implementation. The sample could be further performance optimized and make use of WeakReferences, so it does not require manual disposition.
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.BooleanProperty;
import javafx.collections.*;
public class AllTrueBinding extends BooleanBinding {
private final ObservableList<BooleanProperty> boundList;
private final ListChangeListener<BooleanProperty> BOUND_LIST_CHANGE_LISTENER =
new ListChangeListener<BooleanProperty>() {
#Override public void onChanged(
ListChangeListener.Change<? extends BooleanProperty> change
) {
refreshBinding();
}
};
private BooleanProperty[] observedProperties = {};
AllTrueBinding(ObservableList<BooleanProperty> booleanList) {
booleanList.addListener(BOUND_LIST_CHANGE_LISTENER);
boundList = booleanList;
refreshBinding();
}
#Override protected boolean computeValue() {
for (BooleanProperty bp: observedProperties) {
if (!bp.get()) {
return false;
}
}
return true;
}
#Override public void dispose() {
boundList.removeListener(BOUND_LIST_CHANGE_LISTENER);
super.dispose();
}
private void refreshBinding() {
super.unbind(observedProperties);
observedProperties = boundList.toArray(new BooleanProperty[0]);
super.bind(observedProperties);
this.invalidate();
}
}
And here is a test harness to demonstrate how it works:
import java.util.*;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
public class ListBindingTest {
final BooleanProperty a = new SimpleBooleanProperty(true);
final BooleanProperty b = new SimpleBooleanProperty(true);
final BooleanProperty c = new SimpleBooleanProperty(true);
final BooleanProperty d = new SimpleBooleanProperty(true);
final ObservableList<BooleanProperty> booleanList =
FXCollections.observableArrayList(a, b, c, d);
public static void main(String[] args) {
new ListBindingTest().test();
}
private void test() {
AllTrueBinding at = new AllTrueBinding(booleanList);
System.out.println(at.get() + forArrayString(booleanList));
b.set(false);
System.out.println(at.get() + forArrayString(booleanList));
b.set(true);
System.out.println(at.get() + forArrayString(booleanList));
booleanList.add(new SimpleBooleanProperty(false));
System.out.println(at.get() + forArrayString(booleanList));
booleanList.remove(3, 5);
System.out.println(at.get() + forArrayString(booleanList));
at.dispose();
}
private String forArrayString(List list) {
return " for " + Arrays.toString(list.toArray());
}
}
You can easily implement the method as follows:
public static BooleanBinding conjunction(ObservableList<BooleanProperty> list){
BooleanBinding and = new SimpleBooleanProperty(true).and(list.get(0));
for(int i = 1; i < list.size(); i++){
and = and.and(list.get(i));
}
return and;
}

LWUIT List not scrolling

I have inserted a list in my j2ME project,designed using LWUIT. The code is as follows
Button btnHome;
Button btnExit;
List list;
setScrollableY(false);
setScrollable(false);
list = new List();
MyRenderer render = new MyRenderer();
list.setListCellRenderer(render);
list.getStyle().setFgColor(0xfaedf2);
list.setSmoothScrolling(true);
list.addSelectionListener(new SelectionListener(){
public void selectionChanged(int i, int i1) {
try {
InformationForm form = new InformationForm();
form.show();
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
String[] arrString = builder.getArrName();
System.out.println(arrString.length);
for (int i = 0; i < arrString.length ; i++)
{
list.addItem(arrString[i]);
// System.out.println("item no " + i +" = " +arrString[i] + "added in list");
}
BorderLayout bl=new BorderLayout();
setLayout(bl);
Container holdingContainer=new Container(new FlowLayout(Component.LEFT));
Container c0 = new Container(new BoxLayout(BoxLayout.X_AXIS));
Container c1 = new Container(new FlowLayout(Component.LEFT));
Container c2 = new Container(new FlowLayout(Component.LEFT));
Container footerContainer=new Container(new BoxLayout(BoxLayout.X_AXIS));
c0.addComponent(cityChoice);
c0.addComponent(btnFilter);
//c2.addComponent(list);
c1.setPreferredH(25);
holdingContainer.addComponent(c0);
holdingContainer.addComponent(c1);
getStyle().setBgColor(0x730E36);
// holdingContainer.addComponent(c2);
holdingContainer.setPreferredH(280);
holdingContainer.setScrollableY(true);
addComponent(BorderLayout.CENTER,list);
//addComponent(BorderLayout.WEST,holdingContainer);
footerContainer.getStyle().setMargin(Component.LEFT, 0);
footerContainer.addComponent(btnHome);
footerContainer.addComponent(btnExit);
addComponent(BorderLayout.SOUTH,footerContainer);
The renderer for list is,
public class MyRenderer extends TextArea implements ListCellRenderer{
public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected){
getStyle().setBorder(Border.createEmpty());
getStyle().setFgColor(0xfaedf2);
getStyle().setBgColor(isSelected ? 0x630A2E : 0x730E36);
setText(value.toString());
if (isSelected) {
setFocus(true);
getStyle().setBgTransparency(100);
} else {
setFocus(false);
getStyle().setBgTransparency(0);
}
return this;
}
public Component getListFocusComponent(List list){
return null;}
}
The problem is when on device, i try to scroll the list, the item on which i touched is selected immediatly and the new form for it is opened. I do not able to scroll the list at all. Please help me in solving this problem.
Is it possible you are using a SelectionListener instead of an ActionListener?