35

Which class would work best for a non-ordered list of pairs? I'll be taking a bunch of (float,short) pairs and will need to be able to perform simple math (like multiplying the pair together to return a single float, etc). List only takes one argument, and HashMap won't allow duplicates (as far as I know). Any thoughts?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
V1rtua1An0ma1y
  • 597
  • 2
  • 10
  • 16

8 Answers8

53

You can use the Entry<U,V> class that HashMap uses but you'll be stuck with its semantics of getKey and getValue:

List<Entry<Float,Short>> pairList = //...

My preference would be to create your own simple Pair class:

public class Pair<L,R> {
    private L l;
    private R r;
    public Pair(L l, R r){
        this.l = l;
        this.r = r;
    }
    public L getL(){ return l; }
    public R getR(){ return r; }
    public void setL(L l){ this.l = l; }
    public void setR(R r){ this.r = r; }
}

Then of course make a List using this new class, e.g.:

List<Pair<Float,Short>> pairList = new ArrayList<Pair<Float,Short>>();

You can also always make a Lists of Lists, but it becomes difficult to enforce sizing (that you have only pairs) and you would be required, as with arrays, to have consistent typing.

Mark Elliot
  • 75,278
  • 22
  • 140
  • 160
  • But I would definitely just make the placeholder class and then add instances of it to a list-- call a spade a spade... – Neil Coffey Jan 24 '11 at 00:52
  • Let's say I was going to do this without a new class. I'm thinking of just running two lists of the appropriate type. Why does it complain when I do: private List floatList = new List(); but not when I leave the assignment operator out and just have private List floatList; ? It still needs to be instantiated doesn't it? – V1rtua1An0ma1y Jan 24 '11 at 01:03
  • @V1rtua1An0ma1y: because `List` is an interface, you need an implementation, like, say, `ArrayList` or `LinkedList`. – Mark Elliot Jan 24 '11 at 01:04
  • You have a small typo error in the code, in getL() and getR(), it should be "return l;" and "return r;" instead of "return L;" and "return R;". – Ted Gueniche Dec 26 '12 at 16:51
  • 2
    You might also want to make `Pair` immutable. – Michael Mar 11 '13 at 19:25
  • Sorry, I might sound silly, do we really need a constructor here - what purpose does it solve? – Skynet Jan 23 '16 at 08:11
11

Use a List of custom class instances. The custom class is some sort of Pair or Coordinate or whatever. Then just

List<Coordinate> = new YourFavoriteListImplHere<Coordinate>()

This approach has the advantage that it makes satisfying this requirement "perform simple math (like multiplying the pair together to return a single float, etc)" clean, because your custom class can have methods for whatever maths you need to do...

hvgotcodes
  • 118,147
  • 33
  • 203
  • 236
4

just fixing some small mistakes in Mark Elliot's code:

public class Pair<L,R> {
    private L l;
    private R r;
    public Pair(L l, R r){
        this.l = l;
        this.r = r;
    }
    public L getL(){ return l; }
    public R getR(){ return r; }
    public void setL(L l){ this.l = l; }
    public void setR(R r){ this.r = r; }
}
andresp
  • 1,624
  • 19
  • 31
3

Similar to what Mark E has proposed, but no need to recreate the wheel, if you don't mind relying on 3rd party libs.

Apache Commons has tuples already defined:

org.apache.commons.lang3.tuple.Pair<L,R>

Apache Commons is so pervasive, I typically already have it in my projects, anyway. https://mvnrepository.com/artifact/org.apache.commons/commons-lang3

BruceRV
  • 80
  • 6
1

Sounds like you need to create your own pair class (see discussion here). Then make a List of that pair class you created

Community
  • 1
  • 1
Shezan Baig
  • 1,474
  • 1
  • 14
  • 16
0

Similar to what Mark E has proposed, you have to come up with your own. Just to help you a bit, there is a neat article http://gleichmann.wordpress.com/2008/01/15/building-your-own-literals-in-java-tuples-and-maps/ which gives you a really neat way of creating tuples and maps that might be something you might want to consider.

gbvb
  • 866
  • 5
  • 10
0

If you want multiplicities, you can put it in map that maps pair to ammount. This way there will only be one pair of given values, but it can represent multiple occurances.

Then if you have lot of repeatet values and want to perform some operation on all values, you can save lot of computations.

Alpedar
  • 1,314
  • 1
  • 8
  • 12
0

although HashMap does not allowed duplicated keys it can be used in this way: Map<String, List<String>> mapWithDuplicates = new Map<String, List<String>>();

Jovo Skorupan
  • 237
  • 2
  • 5