Is it possible to have an array that contains two different types of data? I want to have an array that contains a double and also a string. I attempted:
ArrayList<double><String> array;
But that didn't work.
Sorry for the silly question, but it has been a while since I have used something like this.. Can you refresh my memory on how would I declare and populate such an array?
And then to take it a step further, I would like to sort the array by the double if possible?
Thanks!
Firstly, it's worth being clear about the difference between an array and an ArrayList - they're not the same thing at all.
However, in either case you can't do what you want. The closest you can probably come is declaring your own type. (EDIT: My original code had a double or a string... I've now changed it to be a double and a string. Let me know if this change isn't what you had in mind.)
public final class DoubleAndString
{
private final String stringValue;
private final double doubleValue;
public DoubleAndString(String stringValue, double doubleValue)
{
this.stringValue = stringValue;
this.doubleValue = doubleValue;
}
public String getString()
{
return stringValue;
}
public String getDouble()
{
return doubleValue;
}
}
Then create an ArrayList<DoubleAndString> or a DoubleAndString[].
Now, this feels somewhat vanilla at the moment - presumably the double and string values actually have a greater meaning - a name and a score, for example. If so, encapsulate that in a type which describes the pairing more appropriately.
As for ordering - you could make DoubleAndString implement Comparable<DoubleAndString> - but unless that's the only natural ordering which makes sense, I'd write a Comparator<DoubleAndString>:
public class DoubleComparator implements Comparator<DoubleAndString>
{
public int compare(DoubleAndString ds1, DoubleAndString ds2)
{
return Double.compare(ds1.getDouble(), ds2.getDouble());
}
}
Then you can use Collections.sort to sort an ArrayList<DoubleAndString> or Arrays.sort to sort an array.
You can use ArrayList<Object> and you can then use anything you'd like. Encapsulate the double in a Double object and when you retrieve the object use instanceof to check if it's really a double or a String.
I must say, it's unlikely this 'design' would win you any awards. Is it possible to rethink the solution you're considering for your problem, and see if you could do with a different kind of approach?
It sounds like you want a Map. Since you wish to sort the Map, a TreeMap may be optimal.
Map<Double, String> myMap = new TreeMap<Double, String>();
Maps are associative. Each double has an associated string. If you want multiple strings per double, you can use a
Map<Double, ArrayList<String>>
You might already know this, but it is not certainly not a good idea to store different types in a list. By definition an array is a collection of similar objects and stuffing all kinds in it makes things fuzzy. So really you would rather have a separate type to hold these different values.
Well, if you want to have an array with an arbitrary number of elements, then you simply need to use a type that is a common ancestor to both. In this case, that would be Object (since String and Double both inherit from Object). This will require you to check the types, though, when you retrieve or use them.
If you are using a fixed number of multiple different types, then what you really want is a "tuple". However, Java currently does not have an implementation of tuple available. For two items:
public class Pair<T1,T2>
{
public Pair(){
this(null,null);
}
public Pair(T1 x1){
this(x1,null);
}
public Pair(T1 x1, T2 x2){
_x1 = x1;
_x2 = x2;
}
public T1 getFirst(){
return _x1;
}
public T1 getSecond(){
return _x2;
}
private T1 _x1;
private T2 _x2;
}
You can just do ArrayList<object> arraylist and then you can put anything in it, but that may not be what you want.
Then, to sort you would just use your own comparator but, as theatrus mentioned, are these two values supposed to be connected, or do you have a single-dimension array with two different data types?
An ArrayList by definition only contains one object per position. You could do something like this:
List<MyTuple> list = new ArrayList<MyTuple>();
public static class MyTuple implements Comparable<MyTuple> {
private Double doubleValue;
private String stringValue;
//getters and setters
public int compareTo(MyTuple tuple) {
return doubleValue.compareTo(tuple.getDoubleValue());
}
}
You can then use the Collections.sort() method to sort it by the Doubles.
What do you want to do?
If it is not a key value mapping, you should create a new class for this.
You may want to look at the Number base class.
List<Number> list = new ArrayList<Number>();
list.add(new Integer(3));
list.add(new Double(5.2));
You may interpret the numbers as strings, using NumberFormat:
NumberFormat formatter = new DecimalFormat("#.##");
String s = formatter.format(list.get(0));
Though this may not be what you want, you are a bit short on details about your end goal.
if you are basically not trying to do any comparisons/sorting on the ArrayList then you could create something as below:
List list = new ArrayList();
otherwise.. Jon Skeet's answer was best approach.
Related
I have multidimensional double[][] arrays of which each element has a set of properties.
I designed these properties as a Class:
public class ElemProperties
{
public double prop1;
...
}
Linking them with the elements of the array using a HashMap:
HashMap<double[][], ElemProperties> elemProperties;
using it like e.g:
elemProperties.get(exampleArray).getProp1();
However, this only serves as a mapping between the whole array and properties. What I'm trying to do is to actually map the elements. Since Java doesn't have pointers, I'm kind of stuck at this position. This design seems very convoluted is there a better way to achieve this goal?
First attempt would be:
public class Elem {
private double value;
private double additionalProperty1;
private double additionalProperty2;
...
}
And create an Elem[][] instead of a double[][].
This at least works but multi-dimensional arrays aren't too efficient and aren't too expressive either, so the next question is whether you could group them using a different structure.
If the additional properties are optional or could be shared between multiple elements, you would need to write objects for them too, but the starting point is the same.
It is of course possible that you genuinely need a Map to link values to additional properties "because of reasons". In that case you can do something like this:
public class Container {
private double[][] values;
private Map<Double,AdditionalProperties> properties;
public double getValue(int x, int y) {
return values[x][y];
}
public AdditionalProperties getProperties(int x, int y) {
return properties.get( getValue(x, y ) );
}
}
This way you can hide the fact that you use two separate data structures to store the data, and maintain data integrity between them.
Note though that this is semantically very different from the first solution. In particular, positions containing the same value will share their AdditionalProperties.
(There are also practical problems with this implementation, #dasblinkenlight already pointed out why using doubles as keys to a map is an issue, the other is that an autoboxing conversion happens and that can add some memory and run time overhead. All these problems can be overcome with careful coding, but I'm only demonstrating the basic concept here.)
since the HashMap compares for references this works.
Comparing for references also happens to be the biggest problem with this approach: the fact that the object is a 2d array of double does not matter - one could simply replace your map with
HashMap<Object,ElemProperties> elemProperties;
without losing any functionality.
A better approach would be making a class that represents 2D keys based on arrays of double:
class KeyDouble2D {
private final double[][] key;
public KeyDouble2D(double[][] key) {
// Make a copy of key into this.key
}
public boolean equals(Object other) {
// Ensure that other is KeyDouble2D, then compare key
// sizes, and finally compare arrays element-by-element.
// Make sure to use `Double.equals` method to avoid NaN != NaN problem.
}
public int hashCode() {
// Compute hash code as a sum of hash codes in 2D array
}
}
You can use this class for keys of your hash map:
HashMap<KeyDouble2D,ElemProperties> elemProperties = ...;
...
ElemProperties prop = elemProperties.get(new KeyDouble2D(exampleArray)).getProp1();
Note that one needs to be very careful when using arrays of double for hash keys, for the same reason why one needs to be careful when comparing doubles for equality.
Why not create a class DoubleWithProperties, and manipulate an array of this class, instead of using a hashmap?
class DoubleWithProperties {
double value;
ElemProperties props;
public DoubleWithProperties(double value, ElemProperties props){
...
}
}
DoubleWithProperties[][] array = new DoubleWithProperties[5][5];
I have 3 ints named A, B, and C. These are to be multiplied with the number 52. I have a string that contains the name of which int I want to mulitply (in example below my string type == A;.
I want to know if there is anyway to make the name of the String change into the name of the object/int that I wish to use.
What I have right now:
public class MultiplySomeNumbers{
int A = 100;
int B = 200;
int C = 300;
String type = "A";
final int multiplied = 52;
public int multiply(String type){
return multiplied* ____ //What goes here?
}
}
I DON'T want to do anything like this:
public int multiply(String type){
if(type.equalsIgnoreCase("A"){
return multiplied*A;
}else if(type.equalsIgnoreCase("B"){
...
Any help would be greatly appreciated!
No, that is not possible (maybe with Reflection, but it's still a no-go). Every single situation where you think you might need this does not need it.
There are several issues, but here are a few:
No intellisense for those generated variables
Very unclear code
Ambiguous naming (what if you create a new variable that happens to have the same name as a generated one?)
etc etc etc
You will have to go with your second option.
We might be able to provide a different solution, but the question is rather unclear as it is right now. Perhaps you could expand a little so we can help you better.
Although there may be a way to do this with reflection, it's probably a really bad idea. If you really can't just pass in the value, but want to specify a limited set of constants by which you can multiply, I'd recommend creating an enumerated type.
Taking your same example, but using an enum instead of trying to look up constants by name, would look something like this:
public class MultiplySomeNumbers{
public enum Type {
A(100),
B(200),
C(300);
private final int value;
private Type(int value) {
this.value = value;
}
public final int getValue() {
return value;
}
}
Type type = Type.A;
final int multiplied = 52;
public int multiply(Type type){
return multiplied * type.getValue();
}
}
While there is nothing wrong with using an enum for this solution, it may not be the most flexible solution. Enums are, by design, effectively immutable ... they are intended to have the sense of constants. If you wish to change the value of a variable by multiplying its value by 52, then this is not possible with enums.
What I think you really should do is use a HashMap. A Map is a key / value pair.
The key is the "variable's name"; a String quantity
The value is the "variable's current value"; an Integer quantity (not int!)
Your Map can be declared like this:
Map<String, Integer> myVariables = new HashMap<String, Integer>();
then to load your variables into the map, you simply call the Map's put() method:
myVariables.put("A", Integer.valueOf(100));
myVariables.put("B", Integer.valueOf(200));
myVariables.put("C", Integer.valueOf(300));
Retrieving the value of a variable is as simple as using the get() method with your variable name as the key:
int val = myVariables.get("A").intValue();
Notice that I have chosen to box and unbox the primitive int values myself rather than rely on autoboxing. This is just a personal choice. It does trade off conciseness, but I'd rather see what's actually happening.
In my opinion, using reflection to determine a class field to access dynamically at run time is wholly unsatisfactory and should be avoided ... most especially since using the Java Collections API enables a statically typed, type safe solution that can be checked at compile time.
You can't check for a variable's name. For more information look here, there are some good answers:
Java Reflection: How to get the name of a variable?
But maybe a HashMap can help you, where you store "A", "B", "C" as keys and the respective numbers as value.
edit: Okay, maybe with something like this http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Field.html it could be possible.
I have this:
private float dir = 0f;
private boolean ch = true;
private String = "No";
private int aB = 5;
How can I now, make an two dimensional array with this values?
e.g. array1[][]:
{ {0f, "true", "No", 5} }
Or should I make an array like this?
private String array1[][];
Saving all values as a String and then parse each item?
But I think, that this is not a good programming.
You can use an abstract array, IE using Object as the type.
Object array1[][];
However this looks more like you really want a class.
class MyObject {
private float dir;
private boolean ch;
private String str;
private int aB;
// getters and setters omitted
}
and then create an Array or Collection with this: MyObject[] array1. This is usually better design if you can store Objects.
Use objects rather than primitives, e.g.
Object[][] vars = {{ new Float(0f); Boolean.TRUE, "No", new Integer(5) }}
However, I'd have to question why you actually need to do this, possibly a design flaw?
Most of the time it's not a great idea to mix values like that. It's called a jagged array, and many languages let you do it. It's fine in theory but in practice it can make it pretty hard to maintain your code later on.
You generally want to have things really well defined with descriptive variable names. And since Java is a strongly typed language you probably want to make a class that has these values as member variables, and then create an array of that class. Then if you have any special manipulations to make you can make special methods that handle just those values.
Does that make sense?
I am building a class that has a mapping of strings to integers. So if I have 3 apples I would have a mapping of apples to 3.
I need to write a class that sorts the name of the objects by decreasing numbers.
So if I have
(apples, 3)
(oranges, 2)
(bananas, 5)
I will get
(bananas, 5), (apples, 3), (oranges 2)
I was wondering if there's already a class out there that would make my life easier or how I would implement this.
Thanks.
You should be able to put your objects (apples, 3) (oranges, 2) (bananas, 5) into a List and then call Collections.sort(yourlist). You'd then want to make sure the object you declared implements the Comparable interface.
More information is available at http://java.sun.com/docs/books/tutorial/collections/interfaces/order.html
Let's say you declared you object as
public class FruitAndCount implements Comparable<FruitAndCount> {
private final String name;
private final Integer count;
public FruitAndCount(String name, int count) {
this.name = name;
this.count = count;
}
public String name() { return name; }
public int count() { return count; }
public int compareTo(FruitAndCount o) {
return this.count.compareTo(o.count);
}
}
You should then be able to make the following call which will sort your list:
FruitAndCount fruitArray[] = {
new FruitAndCount("Apples", 3),
new FruitAndCount("Oranges", 2),
new FruitAndCount("Bananas", 5)
};
List<FruitAndCount> fruit = Arrays.asList(fruitArray);
Collections.sort(fruit);
You should then have a sorted list of fruit.
It's always nice to be able to make a class implement Comparable, but sometimes you can't, or it is undesirable (for instance, if you need to be able to compare the same type in different ways, based on different attributes).
In this case, it is advisable to use the overloaded Collections.sort() method, which takes a List<T> to sort and a Comparator<T> to determine how the objects should be sorted. This is much cleaner than making new tuples out of your old tuples, and can be more flexible than implementing Comparable (which is also a valid solution).
You really want to take a look at TreeMap.
Assuming the counts are unique, you simply reverse the tuples, storing the count as the key and the name of the fruit as the value. TreeMap then stores the items sorted in ascending order by the key value, and you can read the values back. Since the sorting is done on the insertion the retrieval time is very low.
If you have non-unique counts there's an easy solution here that will let you take advantage of TreeMap.
I have a long piece of code that calculates two values (doubles) for me, I use this piece of code in a few places - to stick with DRY principles I should refactor this bit of code to a nice unit testable method. However I cant make it return two doubles, and doubles are primitive so cannot be passed by value and manipulated. The cleanest way I can think of doing this is by making this method return an double[]. Can anyone think of a better way?
Thanks
Firstly, all variables are passed by value in Java, not just primitives. It's just that objects can be mutable. It's important to understand that. For example:
public void addHour(Date date) {
date.setTime(date.getTime() + 3600 * 1000);
}
The date is passed by value but Date is mutable so it can be modified but try and do this:
public void addHour(Date date) {
date = new Date(date.getTime() + 3600 * 1000);
}
and it won't change the date. Why? Because date is a reference but is passed by value.
Secondly, do these doubles relate to each other in some way? If so wrap them in a class than describes this relationship like:
public class Coordinate {
private final double x;
private final double y;
public Coordinate(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() { return x; }
public double getY() { return y; }
}
You could encapsulate them in a class for this purpose.
You could also give a double[] parameter to the method that calculates them and where it will put the calculated values in. This can be rather efficent as the caller code can reuse this array for successive invocations if performance is important.
A class (immutable) with two double fields? Might even want to add some interesting methods to the class.
The other way around is to have the method take a callback object.
double[] arr = {val1, val2};
return arr
or go with a Pair-like class that encapsulates 2 values...
If the two doubles can be thought of as a logical pairing of values, then it might make sense to bundle them in a simple object?
I'm more of a C++ guy, but creating an object of your own called Pair which can hold 2 doubles and can be passed by reference makes sense to me.
Create an new class that has two double properties with getters and setters and constructor if you like (and equals and hashcode...) and make the method return that type of object. A generic way to do that would be a Pair class. This is a common pattern and you should find code snippets everywhere (e.g. in the netbeans code base).
You have several options:
Return an array
Return a List<double>
Return an object of a class that wraps your two doubles
And by the way, Java does not pass objects by reference. It passes pointers to objects by value.
http://javadude.com/articles/passbyvalue.htm
A double array is the most obvious answer. You can make it a bit safer by having a wrapper object like this:
public class MyTwoDoubles {
public MyTwoDoubles(double one, double two) { ... }
public double getOne() { ... }
public double getTwo() { ... }
}
You can rather use Wrapper classes which are of reference types
For every value type you can find a wrapper class.
for your case java.lang.Double can be used,hope this solves the purpose
But still as a good design i suggest you not to alter the object value inside the method.
Instead refactor the code in such a way you call it twice and return two different values then assign it to the original.
As a good practice its not advisible to alter object value inside a method