How to convert List<Object> into List<List<String>> using Java 8 Stream - stream

Here is what I have:
List<List<String>> listOfLists = new ArrayList<>();
List<DataRow> dataRowList = new ArrayList<>();
DataRow dataRow1 = new DataRow("Ginger Rogers", "Dance Unlimited", "Broadway 23");
DataRow dataRow2 = new DataRow("Fred Astaire", "Rainbow-United", "Wall Street 3");
dataRowList.add(dataRow1);
dataRowList.add(dataRow2);
listOfLists = dataRowList.stream()
.map(this::buildList)
.collect(Collectors.toList());
private List<String> buildList(DataRow dataRow) {
String str = dataRow.getName() + "," + dataRow.getOrganization() + "," + dataRow.getAddress();
return Arrays.asList(str.split(","));
}
I would like to convert dataRowList into ----> listOfLists using Java 8 Stream. Is there a more efficient way?

Related

Can not add a list in document object using iTextSharp

public ActionResult PartTimeFacultyCourseLoadReport()
{
var teacherStatistics = (from t in db.Teachers
join c in db.Courses
on t.Id equals c.TeacherId into cGroup
where t.Status == "Part Time"
orderby t.Designation descending
select new
{
TeacherInfo = t,
CourseInfo = from cg in cGroup
orderby cg.Code ascending
select cg
}).ToList();
List<TeacherStatistics> teacherStatisticses = new List<TeacherStatistics>();
int count = 0;
foreach (var teacherStatistic in teacherStatistics)
{
TeacherStatistics aTeacherStatistics = new TeacherStatistics();
aTeacherStatistics.Name = teacherStatistic.TeacherInfo.Name;
aTeacherStatistics.Designation = teacherStatistic.TeacherInfo.Designation;
aTeacherStatistics.NumberOfCourse = teacherStatistic.TeacherInfo.NumberOfCourse;
count = 0;
foreach (var courseInfo in teacherStatistic.CourseInfo)
{
if (count != 0)
{
aTeacherStatistics.Courses += ", ";
}
aTeacherStatistics.Courses += courseInfo.Code;
aTeacherStatistics.Courses += "(";
aTeacherStatistics.Courses += courseInfo.Section;
aTeacherStatistics.Courses += ")";
count++;
}
teacherStatisticses.Add(aTeacherStatistics);
}
var document = new Document(PageSize.A4, 50, 50, 25, 25);
var output = new MemoryStream();
var writer = PdfWriter.GetInstance(document, output);
document.Open();
var data = teacherStatisticses.ToList();
document.Add(data);
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment; filename=PartTimeFaculty.pdf");
Response.BinaryWrite(output.ToArray());
document.Close();
return View(teacherStatisticses);
}
I want to pass a list named 'teacherStatisticses' through document object for making a PDF. My code doesn't work. It showed me following Error -
Argument 1: cannot convert from 'System.Collections.Generic.List' to 'iTextSharp.text.IElement'
I assume that you are using some version of itextpdf for the PDF generation.
The error is in the line:
document.Add(data);
There is no way to add plain .NET objects into the PDF document. I can not predict the structure of PDF which you`d like to achieve, but the code mentioned above could be written as:
foreach(var teacher in teacherStatistics)
{
var paragraph = new Paragraph(teacher.ToString()); // instead of teacher.ToString() should be some code which translates teacherStatistics projection to the string representation
document.Add(paragraph);
}
//not tested
A lot of useful samples could be found at
http://developers.itextpdf.com/examples
Basic tutorial for the itextpdf:
http://developers.itextpdf.com/content/itext-7-jump-start-tutorial/chapter-1-introducing-basic-building-blocks

neo4j query extremly slow

I want to create a graph using the neo4jclient , I have a dictionary that hold 2 kinds of object ( documents ,list) ,
Dictionary<Document, List<Concept>>
as you can see ,each document hold a list of concept ,a relationship must be between them (document)<-[:IN]-(concept)
public void LoadNode(Dictionary<Document, List<Concept>> dictionary, GraphClient _client)
{
var d = dictionary.ToList();
var t = dictionary.Values;
string merge1 = string.Format
("MERGE (source:{0} {{ {1}:row.Key.Id_Doc }})", "Document", "Name");
string strForEachDoc = " FOREACH( concept in row.Value | ";
string merge2 = string.Format
("MERGE (target:{0} {{ {1} : concept.Name }})", "Concept", "Name");
string merge3 = string.Format
(" MERGE (source)-[ r:{0} ]->(target)", "Exist");
{_client.Cypher
.WithParam("coll", d)
.ForEach("(row in {coll} | " +
merge1 + " " +
strForEachDoc + " " +
merge2 + " " +
merge3 + "))")
.ExecuteWithoutResults();
}
}
it takes times and Visual studio ran into a bizarre error
"Une exception de première chance de type 'System.AggregateException'
s'est produite dans mscorlib.dll"

how can I connect to database

I use this but I can't connect DataBase
conn1.Open();
using (OracleCommand crtCommand = new OracleCommand);
for connect to Oracle from application
string command = "Enter your command";
OracleConnection orclecon;
orclecon = new OracleConnection(connection);
orclecon.Open();
use this for select commands:
DataSet ds = new DataSet();
using (OracleDataAdapter Oda = new OracleDataAdapter(command, orclecon))
{
Oda.Fill(ds);
}
and use this for insert/update/delete commands:
//used for Oracle command (insert,update,delete) if number of rows that affected >0 return true else return false
using (OracleCommand orclcommand = new OracleCommand(command, orclecon))
{
int n = orclcommand.ExecuteNonQuery();
if (n > 0)
return true;
else
return false;
}
orclecon.Close();
To make it dynamic use this;
string sentence = "";
string formatprototype = "";//This will hold the string to be formatted.
string output="";
public void SearchString()
{
string pattern = #".*[ ]+?[\""]{1}(?<String>[a-zA-Z0-9_]*)[\""]{1}[ ]+?MINVALUE[ ]*(?<MinValue>[-?\d]*)[ ]*MAXVALUE[ ]*(?<MaxValue>[\d]*)[ ]+?[INCREMENT]*[ ]+?[BY]*[ ]+?(?<IncrementBy>[\d]*)[ ]+?[START]*[ ]+?[WITH]*[ ]+?(?<StartWith>[\d]*)[ ]+?[CACHE]*[ ]+?(?<Cache>[\d]*)\s+?";
Regex regex = new Regex(pattern);
Match match = regex.Match(sentence);
Group #string = match.Groups[1];
Group minvalue = match.Groups[2];
Group maxvalue = match.Groups[3];
Group incrementby = match.Groups[4];
Group startswith = match.Groups[5];
Group cache = match.Groups[6];
formatprototype = #"CREATE SEQUENCE ""{0}"" MINVALUE {1} MAXVALUE {2} INCREMENT BY {3} START WITH {4} CACHE {5} NOORDER NOCYCLE";
if (minvalue.Value.StartsWith("-"))
{
output = string.Format(formatprototype, #string, minvalue, maxvalue, incrementby, maxvalue, cache);
}
else if (!minvalue.Value.StartsWith("-"))
{
output = string.Format(formatprototype, #string, minvalue, maxvalue, incrementby, minvalue, cache);
}
MessageBox.Show(output);
}
Assume that SearchString() is the function in which you are doing this stuff.And make sure to assign each string that is extracted from database,to sentence.Try it and reply if it worked or not.

No result with Cypher after batchinserting with indexing

I'm very new to neo4j. I've read this question (Cypher Query not finding Node) but it does not work. I'm getting the error, the the auto_node_index was not found. Perhaps it is because I'm using the BatchInserter?
For my experiment, I'm using neo4j 1.8.2 and the programming language Java with the embedded database.
I want to put some data to the database using the BatchInserter and the BatchInserterIndex like explained on http://docs.neo4j.org/chunked/milestone/batchinsert.html.
BatchInserter myInserter = BatchInserters.inserter(DB_PATH);
BatchInserterIndexProvider indexProvider =
new LuceneBatchInserterIndexProvider( myInserter );
BatchInserterIndex persons =
indexProvider.nodeIndex( "persons", MapUtil.stringMap( "type", "exact" ) );
persons.setCacheCapacity( "name", 10000 );
First I read the data from a TGF-file, create the nodes and put it to the inserter like this:
properties = MapUtil.map("name", actualNodeName, "birthday", birthdayValue);
long node = myInserter.createNode(properties);
nodes.add(node);
persons.flush();
The insert works fine, but when I want to search a node with Cypher, the result is empty
ExecutionEngine engine = new ExecutionEngine( db );
String query =
"start n=node:persons(name='nameToSearch') "
+ " match n-[:KNOWS]->m "
+ " return n.id, m ";
ExecutionResult result = engine.execute( query );
System.out.println(result);
On the other side, when I'm using the Traverser-class and start the search on the rootnode, I receive the nodes wich are connetced by the node with the name "nameToSearch".
Can anybody explain me, why I can't get the nodes with Cypher!
here is the complete method for the batch insert:
public long batchImport() throws IOException{
String actualLine;
ArrayList<Long> nodes = new ArrayList<Long>();
Map<String,Object> properties = new HashMap<String,Object>();
//delete all nodes and edges in the database
FileUtils.deleteRecursively(new File(DB_PATH ));
BatchInserter myInserter = BatchInserters.inserter(DB_PATH);
BatchInserterIndexProvider indexProvider =
new LuceneBatchInserterIndexProvider( myInserter );
BatchInserterIndex persons =
indexProvider.nodeIndex( "persons", MapUtil.stringMap( "type", "exact" ) );
persons.setCacheCapacity( "name", 10000 );
long execTime = 0;
try{
//Get the file which contains the graph informations
FileReader inputFile = new FileReader(UtilFunctions.searchFile(new File(PATH_OUTPUT_MERGED_FILES), "nodesAndEdges").get(0));
LineNumberReader inputLine = new LineNumberReader(inputFile);
// Read nodes up to symbol #
execTime = System.nanoTime();
while ((actualLine=inputLine.readLine()).charAt(0) != '#'){
StringTokenizer myTokenizer = new StringTokenizer(actualLine);
// Read node number
String actualNodeNumber = myTokenizer.nextToken();
// Read node name
String actualNodeName = myTokenizer.nextToken() + " " + myTokenizer.nextToken();
//Read property
myTokenizer.nextToken();
String actualNodePropertyKey = BIRTHDAY_KEY;
String actualNodePropertyValue = myTokenizer.nextToken();
actualNodePropertyValue = actualNodePropertyValue.substring(1, actualNodePropertyValue.length()-1);
// Insert node information
properties = MapUtil.map("name", actualNodeName, "birthday", actualNodePropertyValue, "id", actualNodeNumber);
long node = myInserter.createNode(properties);
nodes.add(node);
persons.flush();
}
// Read edges up to end of file
int countEdges = 0;
while ((actualLine=inputLine.readLine()) != null){
StringTokenizer myTokenizer = new StringTokenizer(actualLine);
// Read start node number
String actualStartNodeNumber = myTokenizer.nextToken();
// Read destination node number
String actualDestinationNodeNumber = myTokenizer.nextToken();
// Read relationship type
String actualRelType = myTokenizer.nextToken();
// Insert node information into ArrayList
int positionStartNode = Integer.parseInt(actualStartNodeNumber);
int positionDestinationNode = Integer.parseInt(actualDestinationNodeNumber);
properties.clear();
if (countEdges == 0) {
myInserter.createRelationship(0, nodes.get(positionStartNode-1), RelType.ROOT, properties);
myInserter.createRelationship(nodes.get(positionStartNode-1), nodes.get(positionDestinationNode-1), RelType.KNOWS, properties);
}
else
{
myInserter.(nodes.get(positionStartNode-1), nodes.get(positionDestinationNode-1), RelType.KNOWS, properties);
}
countEdges++;
}
indexProvider.shutdown();
myInserter.shutdown();
execTime = System.nanoTime() - execTime;
// Close input file
inputLine.close();
inputFile.close();
}
catch (Throwable e){
System.out.println(e.getMessage());
e.printStackTrace();
}
return execTime;
}
Your lacks a call to profiles.add(node, <indexProperties>). Therefore you're never adding anything to the index.
It is crucial that the code using Batchinserter API calls shutdown() on both the BatchInserterIndexProvider and BatchInserter. Maybe you've missed this in your code.
If this does not solve the problem, please post your code.

ExecuteSqlCommand with output parameter

I'm using Entity Framework in an ASP.NET MVC3 application and I'm trying to use the following code:
var token = "";
this.Database.ExecuteSqlCommand("exec dbo.MyUsp", new SqlParameter("token", token));
My stored proc signature is:
CREATE PROCEDURE MyUSP(#token varchar(10) OUT)
(...)
When I use this code I get an error saying that parameter "#token" was expected but not supplied.
How do I tell EF that the token parameter is for output?
I ended up using this to get it working, but I'm sure there's a more optimal way:
var p = new SqlParameter
{
ParameterName = "token",
DbType = System.Data.DbType.String,
Size = 100,
Direction = System.Data.ParameterDirection.Output
};
var resp = this.Database.SqlQuery<String>("exec dbo.usp_GetRequestToken #token", p);
return resp.First();
var outParam = new SqlParameter();
outParam.ParameterName = "OutPutParametname";
outParam.SqlDbType = SqlDbType.Bit;//DataType Of OutPut Parameter
outParam.Direction = ParameterDirection.Output;
db.Database.ExecuteSqlCommand("EXEC ProcedureName #Param1,#Param2 OUTPUT", new SqlParameter("Param1", value), outParam);
object outParamValue = Convert.ToBoolean(outParam.Value);
You need to indicate the direction in the parameter. For example, try something like this:
var p = new SqlParameter("token", token);
p.Direction = ParameterDirection.InputOutput;
this.Database.ExecuteSqlCommand("exec dbo.MyUsp", p);
I solved this issue with following SQL and Entity Framework code
SP :
ALTER PROCEDURE [dbo].[SaveSingleColumnValueFromGrid]
(
#TableName VARCHAR(200),
#ColumnName VARCHAR (200),
#CompareField VARCHAR(200),
#CompareValue VARCHAR(200),
#NewValue VARCHAR(200),
#Result INT OUTPUT
)
AS
BEGIN
DECLARE #SqlString NVARCHAR(2000),
#id INTEGER = 0;
IF #CompareValue = ''
BEGIN
SET #SqlString = 'INSERT INTO ' + #TableName + ' ( ' + #ColumnName + ' ) VALUES ( ''' + #NewValue + ''' ) ; SELECT #id = SCOPE_IDENTITY()';
EXECUTE sp_executesql #SqlString, N'#id INTEGER OUTPUT', #id OUTPUT
END
ELSE
BEGIN
SET #SqlString = 'UPDATE ' + #TableName + ' SET ' + #ColumnName + ' = ''' + #NewValue + ''' WHERE ' + #CompareField + ' = ''' + #CompareValue + '''';
EXECUTE sp_executesql #SqlString
set #id = ##ROWCOUNT
END
SELECT #Result = #id
END
Entity Framework Code :
public FieldUpdateResult SaveSingleColumnValueFromGrid(string tableName, string tableSetFieldName, string updatedValue, string tableCompareFieldName, string uniqueFieldValue)
{
var fieldUpdateResult = new FieldUpdateResult() ;
var isNewRecord = false;
if (string.IsNullOrWhiteSpace(uniqueFieldValue))
{
uniqueFieldValue = string.Empty;
isNewRecord = true;
}
using (var dbContext = new DBEntities())
{
var resultParameter = new SqlParameter("#Result", SqlDbType.Int)
{
Direction = ParameterDirection.Output
};
var recordsAffected = dbContext.Database.ExecuteSqlCommand("SaveSingleColumnValueFromGrid #TableName,#ColumnName,#CompareField,#CompareValue,#NewValue,#Result out",
new SqlParameter("#TableName", tableName),
new SqlParameter("#ColumnName", tableSetFieldName),
new SqlParameter("#CompareField", tableCompareFieldName),
new SqlParameter("#CompareValue", uniqueFieldValue),
new SqlParameter("#NewValue", updatedValue),
resultParameter);
fieldUpdateResult.Success = recordsAffected > 0;
if (isNewRecord)
{
fieldUpdateResult.NewId = (int)resultParameter.Value;
}
else
{
fieldUpdateResult.AffectedRows = (int)resultParameter.Value;
}
}
return fieldUpdateResult;
}
var db = new DBContext();
var outParam = new SqlParameter
{
ParameterName = "#Param",
DbType = System.Data.DbType.String,
Size = 20,
Direction = System.Data.ParameterDirection.Output
};
var r = db.Database.ExecuteSqlCommand("EXEC MyStoredProd #Param OUT",outParam );
Console.WriteLine(outParam.Value);
The main part i see everyone is missing, is the OUT keyword needed after #Param.
Below is what I do for Oracle using the DevArt driver. I have a package.proc called P_SID.SID_PGet that returns a single string value. The proc is:
PROCEDURE SID_PGet(io_SID OUT varchar2) is
Begin
io_SID:=GetSID; -- GetSID just goes off and gets the actual value
End;
Below is how I call it and retrieve the SID value (I'm using this with EF 4.1 code first and this method is in the DbContext):
/// <summary>
/// Get the next SID value from the database
/// </summary>
/// <returns>String in X12345 format</returns>
public string GetNextSId()
{
var parameter = new Devart.Data.Oracle.OracleParameter("io_SID", Devart.Data.Oracle.OracleDbType.VarChar, ParameterDirection.Output);
this.Database.ExecuteSqlCommand("BEGIN P_SID.SID_PGet(:io_SID); END;", parameter);
var sid = parameter.Value as string;
return sid;
}

Resources