I begin with Java 8 and i have a migration project. I have read a lot of documentation and tutorial to use foreach or streams but i have a little last problem. I don't find the answer, just tutorial easy example.
I'm trying to transform this loop :
for ( Map.Entry<Neuron, Double> entry: this.entries.entrySet() ) {
value += entry.getKey().getExitValue() * entry.getValue();
}
This solution doesn't match and i know why (anonymous class => final/local var)
this.entries.forEach( (neuron, weight) -> {
value += neuron.getExitValue() * weight;
});
But only with a foreach i don't know how do this simple operation.
I think it's very easy but...
I have try with stream but i have similar problems.
Double sum = entries.entrySet()
.stream()
.forEach( entry-> { ? } );
Thanks you in advance.
As #Holger said in the comments above - in this case it is better to use mapToDoble. However there is still a way to do it using forEach loop. Please note that it is an ugly, dirty trick and it is just for demonstration purposes and it shouldn't be used in production code. As we know only final or effectively final variables can be used with lambda expressions, that's why value += is an illegal expression. Java-8 added a few new classes to java.util.concurrent.atomic one of them is DoubleAdder. You can use it with lambda:
DoubleAdder adder = new DoubleAdder();
stream.forEach(e -> adder.add(e.getKey().getExitValue() * e.getValue()));
System.out.println(adder.sum());
I don't see any cases when this should be used instead of mapToDouble
I introduced a list to stall the values and then do calculation with list.
final List<BigDecimal> valuesList = new ArrayList<>();
otherList.stream().forEach(val-> valuesList.add(map.get(val)));
final BigDecimal lastValue = valuesList.stream().filter(Objects::nonNull).reduce(BigDecimal.ZERO,BigDecimal::add);
I try to tune my query but I have no idea what I can change:
A screenshot of both tables: http://abload.de/image.php?img=1plkyg.jpg
The relation is: 1 UserPM (a Private Message) has 1 Sender (User, SenderID -> User.SenderID) and 1 Recipient (User, RecipientID -> User.UserID) and 1 User has X UserPMs as Recipient and X UserPMs as Sender.
The intial load takes around 200ms, it only takes the first 20 rows and display them. After this is displayed a JavaScript PageMethod gets the GetAllPMsAsReciepient method and loads the rest of the data
this GetAllPMsAsReciepient method takes around 4.5 to 5.0 seconds each time to run on around 250 rows
My code:
public static List<UserPM> GetAllPMsAsReciepient(Guid userID)
{
using (RPGDataContext dc = new RPGDataContext())
{
DateTime dt = DateTime.Now;
DataLoadOptions options = new DataLoadOptions();
//options.LoadWith<UserPM>(a => a.User);
options.LoadWith<UserPM>(a => a.User1);
dc.LoadOptions = options;
List<UserPM> pm = (
from a in dc.UserPMs
where a.RecieverID == userID
&& !a.IsDeletedRec
orderby a.Timestamp descending select a
).ToList();
TimeSpan ts = DateTime.Now - dt;
System.Diagnostics.Debug.WriteLine(ts.Seconds + "." + ts.Milliseconds);
return pm;
}
}
I have no idea how to tune this Query, I mean 250 PMs are nothing at all, on other inboxes on other websites I got around 5000 or something and it doesn't need a single second to load...
I try to set Indexes on Timestamp to reduce the Orderby time but nothing happend so far.
Any ideas here?
EDIT
I try to reproduce it on LinqPad:
Without the DataLoadOptions, in LinqPad the query needs 300ms, with DataLoadOptions around 1 Second.
So, that means:
I could save around 60% of the time, If I can avoid to load the User-table within this query, but how?
Why Linqpad needs only 1 second on the same connection, from the same computer, where my code is need 4.5-5.0 seconds?
Here is the execution plan: http://abload.de/image.php?img=54rjwq.jpg
Here is the SQL Linqpad gives me:
SELECT [t0].[PMID], [t0].[Text], [t0].[RecieverID], [t0].[SenderID], [t0].[Title], [t0].[Timestamp], [t0].[IsDeletedRec], [t0].[IsRead], [t0].[IsDeletedSender], [t0].[IsAnswered], [t1].[UserID], [t1].[Username], [t1].[Password], [t1].[Email], [t1].[RegisterDate], [t1].[LastLogin], [t1].[RegisterIP], [t1].[RefreshPing], [t1].[Admin], [t1].[IsDeleted], [t1].[DeletedFrom], [t1].[IsBanned], [t1].[BannedReason], [t1].[BannedFrom], [t1].[BannedAt], [t1].[NowPlay], [t1].[AcceptAGB], [t1].[AcceptRules], [t1].[MainProfile], [t1].[SetShowHTMLEditorInRPGPosts], [t1].[Age], [t1].[SetIsAgePublic], [t1].[City], [t1].[SetIsCityShown], [t1].[Verified], [t1].[Design], [t1].[SetRPGCountPublic], [t1].[SetLastLoginPublic], [t1].[SetRegisterDatePublic], [t1].[SetGBActive], [t1].[Gender], [t1].[IsGenderVisible], [t1].[OnlinelistHidden], [t1].[Birthday], [t1].[SetIsMenuHideable], [t1].[SetColorButtons], [t1].[SetIsAboutMePublic], [t1].[Name], [t1].[SetIsNamePublic], [t1].[ContactAnimexx], [t1].[ContactRPGLand], [t1].[ContactSkype], [t1].[ContactICQ], [t1].[ContactDeviantArt], [t1].[ContactFacebook], [t1].[ContactTwitter], [t1].[ContactTumblr], [t1].[IsContactAnimexxPublic], [t1].[IsContactRPGLandPublic], [t1].[IsContactSkypePublic], [t1].[IsContactICQPublic], [t1].[IsContactDeviantArtPublic], [t1].[IsContactFacebookPublic], [t1].[IsContactTwitterPublic], [t1].[IsContactTumblrPublic], [t1].[IsAdult], [t1].[IsShoutboxVisible], [t1].[Notification], [t1].[ShowTutorial], [t1].[MainProfilePreview], [t1].[SetSound], [t1].[EmailNotification], [t1].[UsernameOld], [t1].[UsernameChangeDate]
FROM [UserPM] AS [t0]
INNER JOIN [User] AS [t1] ON [t1].[UserID] = [t0].[RecieverID]
WHERE ([t0].[RecieverID] = #p0) AND (NOT ([t0].[IsDeletedRec] = 1))
ORDER BY [t0].[Timestamp] DESC
If you want to get rid of the LoadWith, you can select your field explicitly :
public static List<Tuple<UserPM, User> > GetAllPMsAsReciepient(Guid userID)
{
using (var dataContext = new RPGDataContext())
{
return (
from a in dataContext.UserPMs
where a.RecieverID == userID
&& !a.IsDeletedRec
orderby a.Timestamp descending
select Tuple.Create(a, a.User1)
).ToList();
}
}
I found a solution:
At first it seems that with the DataLoadOptions is something not okay, at second its not clever to load a table with 30 Coloumns when you only need 1.
To Solve this, I make a view which covers all nececeery fields and of course the join.
It reduces the time from 5.0 seconds to 230ms!
I use the following code to prefil a field with an amount from a database.
$amount = db_result(db_query('SELECT amount FROM {table} WHERE nid = %d', $fid));
$node->edit_user_fid = $amount;
If the query doesnt find anything it just shows empty. How can I get the value to be 0 if theres no results?
$node->edit_user_fid = ($amount) ? $amount : 0;
Or also writeable as
if (!$amount) {
$node->edit_user_fid = 0;
}
or if you're sure that $amout is numerical (and it should be), use
$node->edit_user_fid = intval($node->edit_user_fid);
if amount is an int, you can use intval() or an (int) cast so you will always get a numeric value.
db_result() returns FALSE when it cannot find any table row matching the query being executed. Just cast the returned value to an integer.
$node->edit_user_fid = (int) db_result(db_query('SELECT amount FROM {table} WHERE nid = %d', $fid));
PHP manual
-.- you can use ===false or ===0 to teste if it's zero or false (test type and value)
no need to test false and reset to 0 or to set type of variable
var depts = ctx.Departments
.OrderBy(d => d.deptName)
.Select(d => d.deptNo);
foreach (int deptNumber in depts) {
var deptReports = from d in ctx.Departments
join r in matchingIncidents on d.deptNo equals r.deptNo
where r.deptNo == deptNumber
select r;
int deptReportsCount = deptReports.Count();
I am completely baffled! All the questions about this error say to use == on primitive fields (such as IDs), which I'm doing. Anything I do to this query generates the exception. The exact same code worked before and I don't know what I've done to it! Could someone please explain to me what's going on?
Also, I remember there being an EntityFramework class with methods that allowed you to convert objects within a query (e.g. dates), does anyone know what this class is?
UPDATE:
Here are the changes I made (it now works).
var deptReports = from r in matchingIncidents
join d in ctx.Departments on r.deptNo equals d.deptNo
where r.deptNo == deptNumber
select r;
matchingIncidents looks like a local collection of a complex type (because you are using r.deptNo). That's not allowed in LINQ to Entities. You could try this instead:
foreach (int deptNumber in depts) {
var deptReports = from d in ctx.Departments
join r in matchingIncidents.Select(m => m.deptNo)
on d.deptNo equals r
where r == deptNumber
select r;
int deptReportsCount = deptReports.Count();
matchingIncidents.Select(m => m.deptNo) is now a local collection of primitive types and deptReports is a sequence of int (assuming that deptNo is of type int). But for counting the resulting elements it should be still fine.
Edit
And you are probably searching for the static EntityFunctions class:
http://msdn.microsoft.com/en-us/library/system.data.objects.entityfunctions.aspx
Could the issue be:
join r in matchingIncidents on d.deptNo == r.deptNo
Could someone explain why the FLEX 4.5 XMLDecoder does this to my XML-data?
var decoder:XMLDecoder = new XMLDecoder;
var $object:Object = decoder.decode( <xmltag>08.00</xmltag> );
// object = "08.00"
var decoder:XMLDecoder = new XMLDecoder;
var $object:Object = decoder.decode( <xmltag>11.00</xmltag> );
// Object = "11" (HEY! Where did my '.00' part of the string go?)
var decoder:XMLDecoder = new XMLDecoder;
var $object:Object = decoder.decode( <xmltag>11.30</xmltag> );
// Object = "11.3" (HEY! Where did my '0' part of the string go?)
The Flex deserializer also gave me issues with this. It may be interpreting them as Number objects and thus they will return short representations when toString() is called.
Try using .toFixed(2) whenever you need to print a value such as 11.00
var $object:Object = decoder.decode( <xmltag>11.00</xmltag> );
trace($object); //11
trace($object.toFixed(2)); //11.00
So, to the answer the original question of why this is happening:
In the source code for SimpleXMLDecoder (which I'm guessing has similar functionality to XMLDecoder), there's a comment in the function simpleType():
//return the value as a string, a boolean or a number.
//numbers that start with 0 are left as strings
//bForceObject removed since we'll take care of converting to a String or Number object later
numbers that start with 0 are left as strings - I guess they thought of phone numbers but not decimals.
Also, because of some hacky implicit casting, you actually have three different types -
"0.800" : String
11 : int
11.3: Number