I just want ask, is it possible to initiliaze more objects with same constructor in one command?
Example of code:
Tile[] tiles = new Tile(5,5)[20];
Thanks for response.
Impossible as far as I know.
The code Tile[] tiles = new Tile[20]; just creates an array of references. To fill the array, you should create a Tile object and then assign the reference to one index of the array, such as:
tiles[0] = new Tile(5,5);
If all elements of the array pointing to the same object is OK, you can full fill the array simply use:
Tile tiles = new Tile[20];
Arrays.fill(tiles, new Tile(5,5));
No, you have to use a loop.
Tile[] tiles = new Tile[20];
for(int i = 0; i < tiles.length; i++) {
tiles[i] = new Tile(5, 5);
}
However, it is nice that in Java 8 we will be able to shorten this using the new Supplier class and a helper method.
static <E> E[] fill(E[] arr, Supplier<? extends E> supp) {
for(int i = 0; i < arr.length; i++) {
arr[i] = supp.get();
}
return arr;
}
We can then do the following:
Tile[] tiles = fill(new Tile[20], () -> new Tile(5, 5));
I think that's sort of nifty.
There's also a couple ways to do this without Java 8 by using reflection. Here's a way you can do it if the class has a copy constructor (a constructor that takes an object of its own class as an argument):
static <E> E[] duplicate(E[] arr, E element) {
#SuppressWarnings("unchecked")
Class<? extends E> cls = (Class<? extends E>)element.getClass();
try {
Constructor<? extends E> ctor = cls.getConstructor(cls);
for(int i = 0; i < arr.length; i++) {
arr[i] = ctor.newInstance(element);
}
} catch(Exception e) {
e.printStackTrace(System.err);
}
return arr;
}
So for example:
String[] arr = fill(new String[5], "Hello world!");
Reflection is a bit more unstable than the lambda, especially when dealing with subtypes and primitives. The lambda is great.
First, it is even not possible to initialize an object array with non-null value in one line (ok, except using {...} or filling them with same reference but I think it is not what you want)
You gotta create instance of array first, and fill individual element in the array:
e.g.
Foo[] myArray =new Foo[10];
for (int i = 0; i < myArray.length; ++i) {
myArray = new Foo();
}
If you are just looking for shorter code that you don't want to write the loop again and again, here is one option for you:
write a little util like this:
public class ArrayUtil {
public static T[] fillArray(T[] array, ArrayElementFactory elementFactory) {
for (int i = 0; i< array.length; ++i) {
array[i] = elementFactory.create(i);
}
return array;
}
}
public interface ArrayElementFactory<T> {
T create(int i);
}
The way to use is something like
Foo[] fooArray = fillArray(new Foo[10], new ArrayElementFactory<Foo>() {
Foo create(int i) { return new Foo(10,10); }};
If you are using Java8, I believe (haven't tried) you can use lambda expression which give you something like
Foo[] fooArray = fillArray(new Foo[10], i -> new Foo(10,10));
Related
I keep getting a "collections is private" error. I wanted to create an ArrayList. How do you properly extend the Collections class?
import java.util.Collections;
public class lists extends Collections {
public static void main(String[] args) {
Arraylist <Integer> x = new Arraylist<>();
int[] y = new int[100];
for(int i = 0; i<100-1; i++) {
y[i] = i;
}
for(int j = 0; j<100-1; j++) {
Integer z = new Integer(y[j]);
x.set( j , z );
System.out.println(x.get(j));
}
}
}
Perhaps if you are only trying to use ArrayList then you don't need to extend that.
It's ArrayList (not Arraylist)
Use y.length on your first loop rather than 100-1.
You can just use x.add() to add your integer value in without setting index it should be added into since there you are strictly specifying a pattern.
Try this solution:
import java.util.ArrayList;
public static void main (String[] args) throws java.lang.Exception
{
ArrayList <Integer> x = new ArrayList<Integer>();
int[] y = new int[100];
for(int i = 0; i<y.length; i++){
y[i] = i;
}
for(int j = 0; j<100-1; j++){
x.add(new Integer(y[j]));
System.out.println(x.get(j));
}
}
But, here is better solution, same achievement with one loop:
public static void main (String[] args) throws java.lang.Exception
{
ArrayList <Integer> x = new ArrayList<>();
for(int j = 0; j<100-1; j++){
x.add(new Integer(j));
System.out.println(x.get(j));
}
}
First off, if all you want to do is create an instance of ArrayList, there's no reason to extend anything. In your example code there's no need for it.
If you really do want your own collection class, then Collections is the wrong class. You need to implement Collection<E>, singular, or List<E>.
Implementing those interfaces is a lot of work. You can save a lot of time by sub-classing AbstractList<E>. When you do that you only have to implement get(int) and size(); the rest is done for you. If the list is modifiable then you'll also want to override set(int, E), add(int, E), and remove(int).
From the source of Collections class. Collections class is non-instantiable since it has a private constructor. If you have a Subclass which calls the Collections class, the subclass will invoke the super class constructor since the super class does not define any other constructor to invoke. You cannot instantiate the Collections super class and its sub-classes.
// Suppresses default constructor, ensuring non-instantiability.
private Collections() {
}
From your question, if you want to just instantiate an ArrayList class. The line ArrayList <Integer> x = new ArrayList<>(); will suffice with an import of java.util.ArrayList.
Check your code and add variables where needed and you can improve further on the logic.
final int RANGEVAL = 100;
for(int i = 0; i < RANGEVAL -1 ; i++) {
x.set( i , i ); //You can also use x.add(i);
System.out.println(x.get(i));
}
I've just started working with Java for a Data Strutures and Algorithms class (my background is mainly C++) and I've run into something quite clunky in my first assignment.
We were to create a "set" data structure - a bag that does not accept duplicates. From what I can tell, this is essentially just an ArrayList with some extra checks made during the add().
It all works, but I was forced to do something quite clunky when returning the set as an array:
class Set<T> implements SetInterface<T> {
// Properties
private ArrayList<T> _set = new ArrayList<T>();
// Methods
public Object[] toArray() {
return this._set.toArray();
}
}
public static void main(String[] args) {
SetInterface<Integer> mySet = new Set<Integer>();
// set is filled, other tests are performed...
Object[] myArray = mySet.toArray().clone();
for (int i = 0; i < myArray.length; i++)
System.out.print((int)myArray[i] + " ");
}
I originally tried to return an array of type T[] but that threw ClassCastException:
public T[] toArray() {
#SuppressWarnings("unchecked")
T[] temp = (T[])new Object[this._set.size()];
temp = this._set.toArray(temp);
return temp;
}
public static void main(String[] args) {
SetInterface<Integer> mySet = new Set<Integer>();
// set is filled, other tests are performed...
Integer[] myArray = mySet.toArray().clone();
for (int i = 0; i < myArray.length; i++)
System.out.print(myArray[i] + " ");
}
Now, my solution up top works, but it just... feels wrong. Is there a more elegant way to accomplish this? That is, is there a way to avoid having to cast each element in the array after the fact?
Hope this is clear.
Hi I'm very new to Java and in this code, I think I'm not creating the Bag correctly in the Main? Please help thanks!
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable;
at mid.Bag.(Bag.java:12)
at mid.Bag.main(Bag.java:91)
public class Bag<T extends Comparable<T>> implements Iterable<T> {
private int MAX_ITEMS = 10; // initial array size
private int size;
private T[] data;
public Bag( ) {
data = (T []) new Object[MAX_ITEMS];
size = 0;
}
public void add(T newItem) {
// check if it's full, then extend (array resizing)
if (size == data.length) {
T[ ] temp = (T [ ] ) new Object[data.length*2];
for (int i = 0; i < size; ++i)
temp[i] = data[i];
// reassign data to point to temp
data = temp;
}
// then do the assignment
data[size++] = newItem; // assign newItem in the next-available slot
}
public Iterator<T> iterator() {
return new BagIterator();
}
/***************************
* nested class BagIterator
***************************/
class BagIterator implements Iterator<T> {
// instance member
private int index;
// (0) constructor
public BagIterator() {
index = 0;
}
// (1)
public boolean hasNext() {
return (index < size); // size in the outer Bag<E>
}
// (2)
public T next() {
/*
T temp = data[index]; // save the element value
index++; // increment index
return temp;
*/
return data[index++];
}
public static void main(String[ ] args) {
Bag<String> bag1=new Bag<String>();
bag1.add("good");
bag1.add("fortune");
bag1.add("billionarie");
for (String x: bag1)
System.out.println(x);
}
Yes, you're creating an Object[] and then trying to cast it to T[], which the compiler is converting to a cast to Comparable[] (using the raw Comparable type) due to your constraint on T.
Arrays and generics don't work terribly nicely together, basically.
It would probably be simpler to make your data field just an Object[] and cast individual values where necessary.
Here:
data = (T []) new Object[MAX_ITEMS];
you are constructing an Object array and trying to cast it to T[]. But you have declared that T inherits from Comparable. So use:
data = (T []) new Comparable[MAX_ITEMS];
You can probably rewrite your constructor as well:
public Bag(Class<T> c, int s) {
// Use Array native method to create array of a type only known at run time
#SuppressWarnings("unchecked")
final T[] dataArray = (T[]) Array.newInstance(c, s);
this.data = dataArray;
}
Then you can use it like:
Bag<String> bag1 = new Bag<>(String.class,10);
That should also work, IMO. The instances of T must be comparable in any case.
I'm learning Android and Java i have created a class let's say like this
class x(){
public int a;
public string b;
}
and then i initiate a list of this class and then added values to its properties like this
public ArrayList<x> GetList(){
List<x> myList = new ArrayList<x>();
x myObject = new x();
myObject.a = 1;
myObject.b = "val1";
mylist.add(x);
y myObject = new y();
myObject.a = 2;
myObject.b = "val2";
mylist.add(y);
return myList;
}
My Question is how can i loop through what GetList() return
i have tried
ArrayList<x> list = GetList();
Iterator<x> iterator = list.iterator();
but i don't know if this is the right way of doing this, plus i don't know what to do next i have added a breakpoint on the Iterator but it seemed to be null , the list have values thought
There are two ways to do this:
A for loop
Using the iterator method.
for loop:
for(x currentX : GetList()) {
// Do something with the value
}
This is what's called a "for-each" loop, and it's probably the most common/preferred method of doing this. The syntax is:
for(ObjectType variableName : InCollection)
You could also use a standard for loop:
ArrayList<x> list = GetList();
for(int i=0; i<list.size(); i++) {
x currentX = list.get(i);
// Do something with the value
}
The syntax for this is:
for(someStartingValue; doSomethingWithStartingValue; conditionToStopLooping)
iterator method:
Iterator<x> iterator = GetList().iterator();
while(iterator.hasNext()) {
x currentX = iterator.next();
// Do something with the value
}
You can loop through your array with a for-each loop:
for (x item: GetList()) {
doSomethingWithEachValue(item);
}
I guess you can iterate through the arraylist a number of ways. One way is the iterator:-
ArrayList<String> al = new ArrayList<String>();
al.add("C");
al.add("A");
al.add("E");
al.add("B");
al.add("D");
al.add("F");
System.out.print("Original contents of al: ");
Iterator<String> itr = al.iterator();
while (itr.hasNext()) {
String element = itr.next();
System.out.print(element + " ");
}
Another way would be a loop:
for(int i = 0; i < list.size(); i++){
list[i].a = 29;
}
Hope this helps in any way.
Ref
http://www.tutorialspoint.com/java/java_using_iterator.htm
http://examples.javacodegeeks.com/core-java/util/arraylist/arraylist-in-java-example-how-to-use-arraylist/
UPDATE
I thought that I should just put this out there from research due to the comment below about performance.
The Android docs
http://developer.android.com/training/articles/perf-tips.html
states:
The enhanced for loop (also sometimes known as "for-each" loop) can be used for collections >that implement the Iterable interface and for arrays. With collections, an iterator is >allocated to make interface calls to hasNext() and next(). With an ArrayList, a hand-written >counted loop is about 3x faster (with or without JIT), but for other collections the enhanced >for loop syntax will be exactly equivalent to explicit iterator usage.
There are several alternatives for iterating through an array:
static class Foo {
int mSplat;
}
Foo[] mArray = ...
public void zero() {
int sum = 0;
for (int i = 0; i < mArray.length; ++i) {
sum += mArray[i].mSplat;
}
}
public void one() {
int sum = 0;
Foo[] localArray = mArray;
int len = localArray.length;
for (int i = 0; i < len; ++i) {
sum += localArray[i].mSplat;
}
}
public void two() {
int sum = 0;
for (Foo a : mArray) {
sum += a.mSplat;
}
}
zero() is slowest, because the JIT can't yet optimize away the cost of getting the array length once for every iteration through the
loop.
one() is faster. It pulls everything out into local variables,
avoiding the lookups. Only the array length offers a performance
benefit.
two() is fastest for devices without a JIT, and indistinguishable
from one() for devices with a JIT. It uses the enhanced for loop
syntax introduced in version 1.5 of the Java programming language.
So, you should use the enhanced for loop by default, but consider a hand-written counted loop for performance-critical ArrayList iteration. Also this is stated by Josh Bloch's Effective Java, item 46. The iterator and the index variables are both just clutter. Furthermore, they represent opportunities for error.
The preferred idiom for iterating over collections and arrays
for(Element e : elements){
doSomething(e);
}
Josh also states when you see the colon : read it as "In". The loop reads as for each element e in elements. I do not claim this work as my own even though I wish it was. If you want to learn more about efficient code then I suggest reading Josh Bloch's Effective Java.
Try the following:
class x {
public int a;
public String b;
}
private void test() {
List<x> items = getList();
for (x item: items) {
System.out.print("val: " + item.a);
}
}
private List<x> getList() {
List<x> items = new ArrayList<x>();
x oneObject = new x();
oneObject.a = 1;
oneObject.b = "val1";
items.add(oneObject);
x anotherObject = new x();
anotherObject.a = 2;
anotherObject.b = "val2";
items.add(anotherObject);
return items;
}
I want a function / data structure that can do this:
func(int dim){
if(dim == 1)
int[] array;
else if (dim == 2)
int[][] array;
else if (dim == 3)
int[][][] array;
..
..
.
}
anyone know how?
Edit
Or you could use Array.newInstance(int.class, sizes). Where sizes is an int[] containing the desired sizes. It will work better because you could actually cast the result to an int[][][]...
Original Answer
You could use the fact that both int[] and Object[] are Objects. Given that you want a rectangular multidimensional array with sizes given by the list sizes
Object createIntArray(List<Integer> sizes) {
if(sizes.size() == 1) {
return new int[sizes.get(0)];
} else {
Object[] objArray = new Object[sizes.get(0)];
for(int i = 0; i < objArray.length; i++) {
objArray[i] = createIntArray(sizes.subList(1, sizes.size());
}
return objArray;
}
}
You lose all static type checking, but that will happen whenever you want a dynamically dimensioned array.
If your purpose is to create a truly dynamic array, then you should look at the Array object in the JDK. You can use that to dynamically generate an array of any dimension. Here is an example:
public void func(int dim) {
Object array = Array.newInstance(int.class, new int[dim]);
// do something with the array
}
Once the array Object has been created, you can use the methods of the java.lang.reflect.Array class to access, add, remove elements from the multi-dimension array that was created. In also includes utility methods to determine the length of the array instance.
You can even check the dimension of the array using:
public int getDimension(Object array) {
int dimension = 0;
Class cls = array.getClass();
while (cls.isArray()) {
dimension++;
cls = cls.getComponentType();
}
return dimension;
}
People have post good solutions already, but I thought it'd be cool (and good practice) if you wrap the dynamic multidimensional array into a class, which can use any data structure to represent the multi-dimensional array. I use hash table so you have virtually unlimited size dimensions.
public class MultiDimArray{
private int myDim;
private HashMap myArray;
public MultiDimArray(int dim){
//do param error checking
myDim = dim;
myArray= new HashMap();
}
public Object get(Integer... indexes){
if (indexes.length != myDim){throw new InvalidArgumentException();}
Object obj = myArray;
for (int i = 0; i < myDim; i++){
if(obj == null)
return null;
HashMap asMap = (HashMap)obj;
obj = asMap.get(indexes[i]);
}
return obj;
}
public void set(Object value, Integer... indexes){
if (indexes.length != myDim){throw new InvalidArgumentException();}
HashMap cur = myArray;
for (int i = 0; i < myDim - 1; i++){
HashMap temp = (HashMap)cur.get(indexes[i]);
if (temp == null){
HashMap newDim = new HashMap();
cur.put(indexes[i], newDim);
cur = newDim;
}else{
cur = temp;
}
}
cur.put(indexes[myDim -1], value);
}
}
and you can use the class like this:
Object myObj = new Object();
MultiDimArray array = new MultiDimArray(3);
array.put(myObj, 0, 1, 2);
array.get(0, 1, 2); //returns myObj
array.get(4, 5, 6); //returns null
What about a class like following?
class DynaArray {
private List<List> repository = new ArrayList<List>();
public DynaArray (int dim) {
for (int i = 0; i < dim; i++) {
repository.add(new ArrayList());
}
}
public List get(int i) {
return repository.get(i);
}
public void resize(int i) {
// resizing array code
}
}