```
public RandomListNode copyRandomList(RandomListNode head)
{
if(head == null)
return null;
HashMap<RandomListNode,RandomListNode> hashMap = new HashMap<RandomListNode,RandomListNode>();
RandomListNode headNode = null;
RandomListNode tailNode = null;
for(RandomListNode node = head; node != null; node = node.next)
{
RandomListNode newNode;
if(!hashMap.containsKey(node))
{
newNode = new RandomListNode(node.label);
hashMap.put(node,newNode);
}
else
newNode = hashMap.get(node);
RandomListNode random = node.random;
if(hashMap.containsKey(random))
{
newNode.random = hashMap.get(random);
}
else if(random == null)
{
newNode.random = null;
}
else
{
RandomListNode newRandom = new RandomListNode(random.label);
hashMap.put(random,newRandom);
newNode.random = newRandom;
}
if(node != head)
{
tailNode.next = newNode;
tailNode = newNode;
}
else
{
headNode = newNode;
tailNode = newNode;
}
}
return headNode;
}
```

The main difficulty is how to obtain the object's reference that random pointer points to. We can use a hashmap to store such a pair of values: the source node and its corresponding copy node.