Merging two ArrayLists with 2 different objects(which are the instance of the same class) - class

I just want to merge two ArrayLists and have the contents in one ArrayList. Both lists contain the object which is an instance of the same class.
The object reference themselves are different though. However I am getting this unexpected size for the combined arraylist. I use JAVA 1.4
ArrayList a1 = new ArrayList();
ArrayList b1 = new ArrayList();
ClassA cls1A = new ClassA();
ClassA cls1B = new ClassA();
a1.add(cls1A);
b1.add(cls1B);
a1.size() = 100;
b1.size() = 50;
//merge the two arraylist contents into one
//1st method and its result
a1.addAll(b1);
//Expected Result
a1.size = 150
//but
//Obtained result
a1.size = 6789
//2nd method and its result
Collections.copy(a1, b1)
//Expected result
a1.size() = 150
//but
//Obtained result
a1.size = 6789
How can I have an ArrayList which displays the combined size??

I came up with the following solution. First get the size of both the arraylists, then increase the capacity(by using ensureCapacity method of ArrayList class) of the arraylist to which the two needs to be merged. Then add the objects of the 2nd arraylist from the last index of the first arraylist.
a1.add(cls1A);
b1.add(cls1B);
int p = a1.size();
int w = b1.size();
int j = (p + w);
a1.ensureCapacity(j);
for(int r = 0; r <w; r++)
{
ClassA cls1B = new ClassA();
Object obj = b1.get(r);
cls1B = (ClassA)obj;
a1.add(p, cls1B);
p++;
}

Related

KDB: how do I do bulk insert in Java?

I have a table with String columns "key1", "col1", "col2", "col3". I have a snippet below to test the bulk insert. When I run it, I don't get any error, yet I don't see any changes to the "test" table.
Did I miss something?
Object[][] data = new Object[4][];
ArrayList<String>[] rec = new ArrayList[4];
rec[0] = new ArrayList<String>();
rec[1] = new ArrayList<String>();
rec[2] = new ArrayList<String>();
rec[3] = new ArrayList<String>();
for (Integer i = 0; i < 10; i++) {
rec[0].add(i.toString() + i.toString() + i.toString());
rec[1].add(i.toString() + i.toString() + i.toString());
rec[2].add(i.toString() + i.toString() + i.toString());
rec[3].add(i.toString() + i.toString() + i.toString());
}
for (int i = 0; i < 4; i++) {
data[i] = rec[i].toArray(new Object[rec[i].size()]);
}
c.Dict dict = new c.Dict(Arrays.asList("key1", "col1", "col2", "col3").toArray(new String[4]), data);
c.Flip flip = new c.Flip(dict);
Object[] updStatement = new Object[] { ".u.upd", "test", flip };
conn.ks(updStatement);
Adding onto what you said, you want to be using the ks() method with 2 arguments.
From the javadoc given in the c.java class:
Use this to
* invoke a function in kdb+ which takes 2 arguments and does not return a value. e.g. to invoke f[x;y] use ks("f",x,y);
* to invoke a lambda, use ks("{x+y}",x,y);
The function .u.upd takes in 2 arguments and, by default, has the same signature as insert:
First argument is a symbol for the table name, which has the type String in Java
Second argument is the records which has the type Object[] in Java
The length of the Object[] in the second argument should be equal to the number of columns. Each Object in the Object[] should itself be an array that has a length equal to the number of records. The order of the inner arrays should be the same order as the columns, and the values of each inner array should have the matching type to the column type in kdb and have the same order as the records.
Your Object[] should look like:
new Object[]{
new Object[]{row1col1, row2col1, /*..., */ rowNcol1},
new Object[]{row1col2, row2col2, /*..., */ rowNcol2},
/* column 3 to column N-1 values */
new Object[]{row1colN, row2colN, /*..., */ rowNcolN}
}
And your ks() method call should look like:
conn.ks(".u.upd", "test", new Object[]{ /*.... */});

Sort/Order an Undetermined Number of Columns (LINQ\Entity Framework)

Need to sort/order a list of data based on an undetermined number of columns (1 or more).
What i'm trying to do is loop through the desired columns and add an OrderBy or ThenBy based on their number to the query'd list, but i'm unsuccessful...
Done this, but it doesn't compile:
var query = GetAllItems(); //returns a IQueriable list of items
//for each selected column
for (int i = 0; i < param.Columns.Length; i++)
{
if (i == 0)
{
query = query.OrderBy(x => x.GetType().GetProperty(param.Columns[i].Name));
}
else
{
//ERROR: IQueriable does not contain a definition for "ThenBy" and no extension method "ThenBy"...
query = query.ThenBy(x => x.GetType().GetProperty(param.Columns[i].Data));
}
}
How can i resolve this issue? Or any alternative to accomplish this requirement?
SOLUTION: #Dave-Kidder's solution is well thought and resolves the compile errors i had. Just one problem, OrderBy only executes (actually sorts the results) after a ToList() cast. This is an issue because i can't convert a ToList back to an IOrderedQueryable.
So, after some research i came across a solution that resolve all my issues.
Microsoft assembly for the .Net 4.0 Dynamic language functionality: https://github.com/kahanu/System.Linq.Dynamic
using System.Linq.Dynamic; //need to install this package
Updated Code:
var query = GetAllItems(); //returns a IQueriable list of items
List<string> orderByColumnList = new List<string>(); //list of columns to sort
for (int i = 0; i < param.Columns.Length; i++)
{
string column = param.Columns[i].Name;
string direction = param.Columns[i].Dir;
//ex.: "columnA ASC"
string orderByColumn = column + " " + direction;
//add column to list
orderByColumnList.Add(orderBy);
}
//convert list to comma delimited string
string orderBy = String.Join(",", orderByColumnList.ToArray());
//sort by all columns, yay! :-D
query.OrderBy(orderBy).ToList();
The problem is that ThenBy is not defined on IQueryable, but on the IOrderedQueryable interface (which is what IQueryable.OrderBy returns). So you need to define a new variable for the IOrderedQueryable in order to do subsequent ThenBy calls. I changed the original code a bit to use System.Data.DataTable (to get a similar structure to your "param" object). The code also assumes that there is at least one column in the DataTable.
// using System.Data.DataTable to provide similar object structure as OP
DataTable param = new DataTable();
IQueryable<DataTable> query = new List<DataTable>().AsQueryable();
// OrderBy returns IOrderedQueryable<TSource>, which is the interface that defines
// "ThenBy" so we need to assign it to a different variable if we wish to make subsequent
// calls to ThenBy
var orderedQuery = query.OrderBy(x => x.GetType().GetProperty(param.Columns[0].ColumnName));
//for each other selected column
for (int i = 1; i < param.Columns.Count; i++)
{
orderedQuery = orderedQuery.ThenBy(x => x.GetType().GetProperty(param.Columns[i].ColumnName));
}
you should write ThenBy after OrderBy like this:
query = query
.OrderBy(t=> // your condition)
.ThenBy(t=> // next condition);

EPPlus chart(pie,barchart) selected(B2,B36,B38) .. etc excel cells

I have similar to the link below problem.
EPPlus chart from list of single excel cells. How?
I tried the code but it shows it twice in the chart. For example:
This code show excel chart -> select data-> horizontal(category) axis labels tab you show 100,100,300,600 write. What is the reason for this? The chart is written twice the first data I did not find a solution to the problem.
I think you just discovered a bug with EPPlus. Shame on me for not noticing that with that post you reference. It seems that when using the Excel union range selector (the cell names separated by commas) the iterator for the ExcelRange class returns a double reference to the first cell, in this case B2.
A work around would be to use the other overload for Series.Add which will take two string ranges. Here is a unit test that show the problem and the workaround:
[TestMethod]
public void Chart_From_Cell_Union_Selector_Bug_Test()
{
var existingFile = new FileInfo(#"c:\temp\Chart_From_Cell_Union_Selector_Bug_Test.xlsx");
if (existingFile.Exists)
existingFile.Delete();
using (var pck = new ExcelPackage(existingFile))
{
var myWorkSheet = pck.Workbook.Worksheets.Add("Content");
var ExcelWorksheet = pck.Workbook.Worksheets.Add("Chart");
//Some data
myWorkSheet.Cells["A1"].Value = "A";
myWorkSheet.Cells["A2"].Value = 100; myWorkSheet.Cells["A3"].Value = 400; myWorkSheet.Cells["A4"].Value = 200; myWorkSheet.Cells["A5"].Value = 300; myWorkSheet.Cells["A6"].Value = 600; myWorkSheet.Cells["A7"].Value = 500;
myWorkSheet.Cells["B1"].Value = "B";
myWorkSheet.Cells["B2"].Value = 300; myWorkSheet.Cells["B3"].Value = 200; myWorkSheet.Cells["B4"].Value = 1000; myWorkSheet.Cells["B5"].Value = 600; myWorkSheet.Cells["B6"].Value = 500; myWorkSheet.Cells["B7"].Value = 200;
//Pie chart shows with EXTRA B2 entry due to problem with ExcelRange Enumerator
ExcelRange values = myWorkSheet.Cells["B2,B4,B6"]; //when the iterator is evaluated it will return the first cell twice: "B2,B2,B4,B6"
ExcelRange xvalues = myWorkSheet.Cells["A2,A4,A6"]; //when the iterator is evaluated it will return the first cell twice: "A2,A2,A4,A6"
var chartBug = ExcelWorksheet.Drawings.AddChart("Chart BAD", eChartType.Pie);
chartBug.Series.Add(values, xvalues);
chartBug.Title.Text = "Using ExcelRange";
//Pie chart shows correctly when using string addresses and avoiding ExcelRange
var chartGood = ExcelWorksheet.Drawings.AddChart("Chart GOOD", eChartType.Pie);
chartGood.SetPosition(10, 0, 0, 0);
chartGood.Series.Add("Content!B2,Content!B4,Content!B6", "Content!A2,Content!A4,Content!A6");
chartGood.Title.Text = "Using String References";
pck.Save();
}
}
Here is the output:
I will post it as an issue on their codeplex page to see if they can get it fixed for the next release.

How to get StratifiedKFold in Scala Spark MLLib

I searched a bit and not finding any - wrote a StratifiedKFold method which can be used with Scala, Spark (MLlib). I am posting the answer below
a java version of stratifiedKFold of JavaRDD.
/*
stritified KFolds. this will promise each category will be fairly splited into training and testing samples.
for example 3 folds, category '0' has 3 samples, then all the 3 output folds will be like: training with 2 samples, testing with 1 samples.
the split will be as fair as possible, like: to split 11 samples into 3, result will be [4, 4, 3].
if the count of one category is less than k, then some folds will not contain samples of this category, this bad split will cause inaccurate result. but this is not mandatory.
*/
private static Tuple2<JavaRDD<LabeledPoint>, JavaRDD<LabeledPoint>>[] stritifyKFolds(JavaRDD<LabeledPoint> data, Broadcast<Integer> kBC){
JavaRDD<List<List<LabeledPoint>>> foldedLP = data.mapToPair( //map to (key,list) pair.
lp -> {
List<LabeledPoint> list = new ArrayList<>();
list.add(lp);
return new Tuple2<>(lp.label(), list);
}
).reduceByKey( //aggregate
(List<LabeledPoint> list1, List<LabeledPoint> list2) -> {
list1.addAll(list2);
return list1; //put the LabeledPoint with the same key into one list.
}
).values() //get list only after aggregate.
.map( //split each list into K folds.
list -> {
//shuffule and then put into different folds.
Collections.shuffle(list);
int total = list.size();
if(total < kBC.value()){
log.warn("category size {} is less than folds number {}, this will break stratification and leads to bad folds splitting", total, kBC.value());
}
//assign each element into folds.
List<List<LabeledPoint>> keyFolds = new ArrayList<>();
int avg = total/kBC.value(); //averge number of elements.
int remain = total - kBC.value(); //remain number of elements, which will be assign to folds from left to right fairly.
for(int i=0, index = 0, count=0; i<kBC.value(); i++, index += count){
//get current folds count
count = (i<remain) ? avg+1 : avg;
keyFolds.add(list.subList(index, index+count));
}
return keyFolds;
}
);
foldedLP.persist(StorageLevel.MEMORY_AND_DISK_SER());
Tuple2<JavaRDD<LabeledPoint>, JavaRDD<LabeledPoint>>[] result = new Tuple2[kBC.value()];
//initialize folds, each fold is a tuple of (training RDD, testing RDD).
for(int i=0; i<kBC.value(); i++){
final int ii = i; //must be final variable if used in lambda.
JavaRDD<LabeledPoint> training_i = foldedLP.flatMap(
list -> {
List<LabeledPoint> noII = new ArrayList<>();
for(int j=0; j<kBC.value(); j++){
if(j != ii){
noII.addAll(list.get(j)); //get the all except ii_th list iterator.
}
}
return noII.iterator();
}
);
JavaRDD<LabeledPoint> testing_i = foldedLP.flatMap(
list -> list.get(ii).iterator() //get the ii_th list iterator.
);
result[i] = new Tuple2<>(training_i, testing_i);
}
foldedLP.unpersist();
return result;
}
def StratifiedKFold(nSamples: Int, k: Int, labels: List[Int],shuffle: Boolean = false): (Map[Int,List[List[Int]]],Int)= {
var idxs = (0 until nSamples).toArray
val unqLabels = labels.distinct
val noOfLabels = unqLabels.length
val idxsbylabel = idxs.groupBy { x => labels(x) }
var stratifiedidxs: Map[Int,List[List[Int]]] = Map(1 -> List(List(1)))
for ( i <- 0 to noOfLabels-1){
val labelsgroup_i_arr = if(shuffle) bshuffle(idxsbylabel(i).toArray) else idxsbylabel(i).toArray
val noOfParts = if(labelsgroup_i_arr.length%k==0) labelsgroup_i_arr.length/k else (labelsgroup_i_arr.length/k)+1
val labelsgroup_i_lst = List.concat(labelsgroup_i_arr)
stratifiedidxs = stratifiedidxs + (i -> labelsgroup_i_lst.grouped(noOfParts).toList)
}
(stratifiedidxs,noOfLabels)
}

Devexpress xtraChart How to assign x and y values?

I have values in datasource and there is no problem with datasource. I have to assign X and Y values to the chart. Chart throws an error and says there is no column with named "TotalInboundArrivals".
ChartControl chart = new ChartControl();
chart.Location = new Point(38, 301);
chart.Size = new Size(789, 168);
Series series = new Series("Series1", ViewType.Bar);
chart.Series.Add(series);
series.DataSource = ds;
series.ArgumentScaleType = ScaleType.Numerical;
series.ArgumentDataMember = "TotalInboundArrivals"; //throws error here
series.ValueScaleType = ScaleType.Numerical;
series.ValueDataMembers.AddRange(new string[] { "StartTime" }); //throws error here
((SideBySideBarSeriesView)series.View).ColorEach = true;
((XYDiagram)chart.Diagram).AxisY.Visible = true;
chart.Legend.Visible = true;
chart.Visible = true;
chart.Dock = DockStyle.Fill;
xtraTabPage1.Controls.Add(chart);
Where is my Problem? Any Suggestions?
Have you went through Series.DataSource Property. You are making the mistake of assigning DataSet as DataSource to series. Think about it, how could it search columns in Data Source. Try to assign Ds.Tables["TableName"] as the datasource.
Creating DataSource Table
private DataTable CreateChartData(int rowCount) {
// Create an empty table.
DataTable table = new DataTable("Table1");
// Add two columns to the table.
table.Columns.Add("Argument", typeof(Int32));
table.Columns.Add("Value", typeof(Int32));
// Add data rows to the table.
Random rnd = new Random();
DataRow row = null;
for (int i = 0; i < rowCount; i++) {
row = table.NewRow();
row["Argument"] = i;
row["Value"] = rnd.Next(100);
table.Rows.Add(row);
}
Specifying Series properties corresponding to datasource
Series series = new Series("Series1", ViewType.Bar);
chart.Series.Add(series);
// Generate a data table and bind the series to it.
series.DataSource = CreateChartData(50);
// Specify data members to bind the series.
series.ArgumentScaleType = ScaleType.Numerical;
series.ArgumentDataMember = "Argument";
series.ValueScaleType = ScaleType.Numerical;
series.ValueDataMembers.AddRange(new string[] { "Value" });
Check the Examples and go through the Creating Charts -> Providing Data section to better understand it.
Reference
Hope this helps.