If you have a number like $6387$, then instead of doing $f(6387)$ you can do $f(6000) + f(300) + f(80) + f(7)$. For any $n$ in the form of $a*10^b$ where $a,b \in \mathbb{Z}$ ,
$f(n) = \begin{cases} ab*10^{b-1} + 10^b & \text{:$b\ge1, a\gt2$} \\ ab*10^{b-1} + (n \bmod 10^b) + 1 & \text{:$b\ge1, a=2$} \\ ab*10^{b-1} & \text{:$b\ge1, a=1$} \\ 1 & \text{:$b=0, a\ge2$} \\ 0 & \text{:$b=0, a\lt2$} \\ \end{cases}$
For an explanation on how that equation works, take the number $6000$. If you put a $2$ in the units place (_ _ _ 2), then for all $4$ digit numbers, $6$ numbers can occupy the first spot, $10$ the second, and $10$ the third. $6*10*10 = 600$. The $2$ can also be placed in the tens and hundreds place, so make that $600*3$. Now a $2$ can also be placed in the thousands place since 2 <= 6, but there can be 10 other digits everywhere else, so it would be $10*10*10$, leaving you with $1800+1000=2800$. (That is the basic logic behind what I did).
I do not know if you are looking for a function, or just an answer. But I know the answer is $28263827$.
import java.io.File; import java.io.PrintWriter; public class test { public static long count = 0; public static void main(String[] args) { long i = 1; find(i); while (i != count) { if(i%100000==0){ System.out.println(i + ":" + count); } i++; find(i); } System.out.println(i); } public static void find(long s) { String s2 = Long.toString(s); char[] chars = s2.toCharArray(); for (char c : chars) { if (c == '2') count++; } } }