2

I'm looking for a way to map multiple keys to the same value without using extra memory by adding this value twice. Normally you would just do:

 Map<Integer, Integer> map = new HashMap<>();
 map.put(065,600);
 map.put(070,600);

But it is my understanding that the value 600 is now stored in memory twice. Is there a way to avoid this such that they point to the exact same value? Thanks a bunch ! Peace out

blah_crusader
  • 424
  • 1
  • 5
  • 14
  • 1
    How memory-consuming do you think is a integer object? Is this too premature? – user202729 Mar 29 '18 at 12:04
  • You can change your map to this : ``Map , Integer>`` – Schidu Luca Mar 29 '18 at 12:05
  • It is to store a huge matrix with integers, where lots of integers are the same value. I'm creating a data structure that can cope with this type of matrices. – blah_crusader Mar 29 '18 at 12:05
  • "Just do it". Create an `Integer` object and then use it. – user202729 Mar 29 '18 at 12:05
  • If you're storing a huge list of `Integer` something is wrong. Consider using `int[]`. See https://stackoverflow.com/a/17511703 – user202729 Mar 29 '18 at 12:06
  • Going wild here, but there's a way to parametrize the high value of the integer cache beyond byte range (see the `java.lang.Integer.IntegerCache.high` property). Would not recommend at all, just worth mentioning :) – Mena Mar 29 '18 at 12:06
  • But a ---pointer--- reference take 4 bytes anyway... – user202729 Mar 29 '18 at 12:07
  • @SchiduLuca This seems promising. Is it possible to iteratively increase List when new values arrive? Then this should work.. – blah_crusader Mar 29 '18 at 12:08
  • You can but that's not a very good. Overall it's a bad idea to use mutable variables as keys in a map. I thought that you have an initial list and it will not change after that. – Schidu Luca Mar 29 '18 at 12:10
  • @user3343378 `IdentityHashMap` maybe? – user202729 Mar 29 '18 at 12:10
  • Also see https://stackoverflow.com/questions/10766906/ – user202729 Mar 29 '18 at 12:11
  • @user202729 The problem I'm trying to solve involves a huge matrix 100,000x100,000 that has for instance only 20 distinct values in total. I'm trying to figure out how to reduce the size of this matrix, by just keeping the 20 distinct values together with location indices of where these values are located on the matrix. Do you think my way of doing it could reduce the size? – blah_crusader Mar 29 '18 at 12:12
  • Why can't you use `int[][]`? / ... Yes. – user202729 Mar 29 '18 at 12:15
  • If I use int[][], I would first have to initialize the array at dimension 100,000x100,000 so memory will be allocated immediately, I thought. I'm trying to reduce memory requirement to less than that.. – blah_crusader Mar 29 '18 at 12:17
  • Maybe it's not possible how I imagined to do it, but basics of java are a bit lacking from my side – blah_crusader Mar 29 '18 at 12:18
  • ... But ... it seems that you're asking the wrong question. If you don't "allocate memory immediately" but still need to store the data at some point in time, you need to allocate memory anyway. How can you avoid doing that? – user202729 Mar 29 '18 at 12:18
  • Well I was thinking that if you have for instance 1 matrix with everywhere the same value, you can reduce memory by just saying 1 integer and the number of times it occurs instead of storing all integers. To the same extent, I thought that if you have several countable numbers occurring repeatedly in a matrix, you don't actually have to store all of them in memory.. No? – blah_crusader Mar 29 '18 at 12:20
  • You're lacking some basic Java knowledge. On typical implementation, a `int` take no more memory than a pointer (reference). And a `HashMap` node definitely cost more memory than two references. – user202729 Mar 29 '18 at 12:22
  • Hmm, so no way to reduce a huge matrix with lots of same values? – blah_crusader Mar 29 '18 at 12:26
  • @user3343378 Arithmetic encoding maybe? 20 different values, each take 4.32 bits, 1e10 values are 5GiB. (if you use `int[][]` each `int` take 32 bits so it's 37GiB, and with HashMap it's definitely larger) What exactly are you trying to do with such a large matrix? – user202729 Mar 29 '18 at 12:28
  • Alternatively, if there is a value that occur much more often than other values (say, `0`), use a hashmap is reasonable. (sparse array) Although this is getting off-topic. – user202729 Mar 29 '18 at 12:33
  • I'm just facing memory constraints to fit a matrix in memory. 20 was just an example, the real number of distinct values present in the matrix depends on user settings of the program.. I looked at arithmetic encoding, I'm gonna check this out, this seems a good idea! Thanks! – blah_crusader Mar 29 '18 at 12:35
  • And yes, this is a sparse array as well. It is firstly sparse, and secondly the values != 0 that will be in there will also be very unevenly distributed; some occur very frequently, some don't. – blah_crusader Mar 29 '18 at 12:36
  • Can't you use some linear algebra for this? It's ages since I don't see such techniques being used, but maybe you could use the SVD (single value decomposition)? See [here](https://diego.assencio.com/?index=82209f7b8bc7c143f4419238ef16c129) for details. – fps Mar 29 '18 at 12:38
  • Speed for creating this matrix is very important, and secondly, a lookup in the original matrix of an element needs to be very rapidly as well. I believe complexity of SVD is an issue here, no? – blah_crusader Mar 29 '18 at 12:41
  • Honestly, I don't remember SVD complexity. However, I think you can't have both speed and little memory consumption. Choose to optimize either one or the other. If you use SVD with orthogonal matrices, maybe you could manage to get an acceptable trade-off by using `BitSet` to represent the orthogonal matrices and an array or `List` for the singular values. But I'm just guessing, you should ask specifically about this. – fps Mar 29 '18 at 12:50
  • 1
    Alright, will consider this.. Thanks guys! – blah_crusader Mar 29 '18 at 12:53

1 Answers1

2

Try this:

 Map<Integer, Integer> map = new HashMap<>();
 Integer i = 600;
 map.put(065,i);
 map.put(070,i);
Andres
  • 10,561
  • 4
  • 45
  • 63