Both are based on the principle of locality. Then why virtual memory uses table lookup while cache memory uses associative memory for block identification?
I think it's because when using virtual memory, you have access to disk and thus have vasts amounts of memory to store extra data structures than can help you identify each page. In cache, you don't have that much memory, so the way to do things is to add identification (tag and set) bits to each cache line so that you don't need another data structure to identify each cache block because it would be expensive memory-wise. You just iterate over each set, identify the set you're looking for, then iterate over each cache line in that set and identify the cache line you're looking for and then extract the desired bytes. Also, iterating over all cache lines is not that expensive because there aren't a lot of them, but applying this technique to pages, which can be thousands, is really inefficient.