A rule of thumb I draw from the article is that if you are using a Pair/other built in type "just this once" you need to ensure that it can only ever be used "just this once" (within reason).
So let's consider a lambda. It is also something that can start out as being used "just this once".
When you pass lambda as a argument for a filter(), you ensure that (within reason), that lambda will only be used for the filter predicate. You needed to tell the filter() how to filter and your filtering condition was special to that situation, so you used a lambda to provide the predicate. You took advantage of the lambda to provide the predicate as concisely as possible.
If you find that predicate (lambda) being needed in more than one place and you decide to store it in a variable, in my opinion you have probably entered the Primitive Obsession territory. You had a good justification to use that lambda "just this once" before, but the situation has changed. You have nothing to lose by converting it to a method with a descriptive name.
So let's go back to the Pair. It is very unlikely that this Pair will just be used just this once to print out the sign up date. You will likely soon find yourself wanting to save, load, filter etc these signups. Every single time you want to add functionality, you need to take that extra little bit of time to check with yourself what this Pair really means.
A way I would check if I am really allowed to use the Pair or other primitive "just this once" is to ask if can "leak" and someone else can get to use it. Then the question is what can happen when it leaks. When someone gets hold of my filter, all they can do it chuck in a item and get out a true or false. If someone finds this Pair sitting there and starts trying to use it, all sorts of havoc can happen if they don't carefully check what is going on elsewhere with that Pair. For example they may overwrite the information, thinking the pair means something else. When you have a SignUp class with a long userId, someone can easily see when they are working with the userid.
Disclaimer: you should not actually let some other class directly access SignUp.userId directly (have getUserId() instead). I just had it this way for the example.
Another way to check is to interrogate your primitive and ask if it really means what you are trying to intend it to mean. When you have a lambda that takes a list item and spits out a true or false, it is a predicate. You can stick it in anything that wants a predicate.
With your Pair, the two fields only have meaning as a SignUp "mentally". Everywhere you want for your code to treat it as a sign-up, you need to tell it where to get the user id and where to get the data. With a predicate, you just know it's going to decide to give the input a thumbs up or a thumbs down.