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));
}
Related
I am trying to write a lambda function in Java 8 that will take any type of List of any object. This simple function will reverse a list, the key thing is I want this function to take a list of any object. The function/class is below:
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
public abstract class ReverseListFunction {
// function which reverses a list
public static Function<List<Object>, List<Object>> reverseList = (List<Object> l) -> {
int midPoint = endIndex/2;
for (int i = endIndex; i > midPoint; i-- ) {
Object temp = l.get(i);
int distanceFromEndIndex = endIndex - i;
l.set(i, l.get(distanceFromEndIndex));
l.set(distanceFromEndIndex, temp);
}
return l;
};
}
I've made it static so I can call it without instantiating the class, as below:
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
List<Integer> ints = new ArrayList<>();
for (int i = 0; i < 100; i++ ) {
// int i is cast to Integer and added to ints
ints.add(i);
}
// This line prevents compilation
ints = ReverseListFunction.reverseList.apply(ints);
}
}
The last line in the segment above gives an error stating that apply(List) cannot be applied to argument ArrayList. I was wondering what is the best way to solve this so my function is able to take such an ArrayList of Integers, or indeed any object.
One idea was to use Generics, however I was then unable to use the function from a static context, and when I changed the function to be called on an instance of ReverseListFunction, it still errored as I was providing an ArrayList, not a List.
So, what would be the functional way, if it exists, of solving this problem?
You don't need to create a lambda to create the Function object. You can create a static method in your class and use a method reference:
public static <T> List<T> reverseList(List<T> l) {
int endIndex = l.size() - 1;
int midPoint = endIndex/2;
for (int i = endIndex; i > midPoint; i-- ) {
T temp = l.get(i);
int distanceFromEndIndex = endIndex - i;
l.set(i, l.get(distanceFromEndIndex));
l.set(distanceFromEndIndex, temp);
}
return l;
}
And use the method reference:
Function<List<Integer>, List<Integer>> reverseFunction = ReverseListFunction::reverseList;
By the way, to reverse a List, there is a method available in Collections, you could do:
Collections.reverse(myList);
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.
Here is just a simple example. Obviously there are simpler ways to set everything up within the constructor, but the arrayList I'm actually working with has already been set up, I just need to change individual sections of it. There HAS to be a way to call a class's functions in ArrayList, but for the life of me I can't figure out how.
import java.util.ArrayList;
public class ArrayTest{
public static void main(String[] args){
//Here's an example of a regular array:
Length[] lArray = new Length[3];
for (int i = 0; i < 3; i++){
lArray[i].setLength(i + 1);
}
//Here's how I was hoping ArrayList would function:
ArrayList<Length> lList = new ArrayList<Length>(3);
for (int i = 0; i < 3; i++){
lList[i].setLength(i + 1);
// --OR--
lList.setLength(i, i + 1);
}
}
}
Here's the length class:
public class Length{
private int length;
Length(){
length = 0;
}
Length(int s){
length = s;
}
public void setLength(int s){
length = s;
}
}
Thanks!
You add elements to the ArrayList with add.
Since it's an ArrayList<Length>, you add Length objects:
lList.add(new Length());
And in your specific loop :
ArrayList<Length> lList = new ArrayList<Length>(3);
for (int i = 0; i < 3; i++){
Length l = new Length();
l.setLength(i+1);
lList.add(l);
}
BTW, the array initialization is also missing an important initialization :
for (int i = 0; i < 3; i++){
lArray[i] = new Length(); // added
lArray[i].setLength(i + 1);
}
If the ArrayList already contains the elements, and you just want to modify them, you can write something like this:
lList.get(i).setLength(i + 1);
assuming that the ArrayList contains the ith element.
You could create a method with your operation/algorithm like
public void foo(){
System.out.println("some algorithm!");
}
inside Length class. This will operate on each instance of Length class.
And for iterating, you can use
ArrayList<Length> lList = new ArrayList<Length>(3);
for (Length l : lList){
l.foo();
}
This will call everything you code inside foo.
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));
I'm trying to create a table class, who's rows and columns may expand or shrink, to store ints and strings as a first Java project. The data structure I'm trying to use to represent the table is an ArrayList of ArrayLists, where the initial array's elements all point to a new array list - so the initial array kind of serves as an entrance into rows. This would be a picture of how I have it in my mind, for reference:
The problem I'm having is accessing the inner ArrayLists. I've been reading a bit of documentation, and I can't seem to understand the big issue with why I'm not able to access the inner lists. Some code here:
import java.util.ArrayList;
public class Table {
private int length, width;
private ArrayList newTable;
public Table() {
this.length = this.width = 0;
}
/**
* Testing a few functions
*/
public static void main(String[] args) {
// Just testing a few functions.
Table list1 = new Table();
list1.createTable(4, 4);
list1.displayRow(1);
list1.displayColumn(1);
System.out.println("displayColumn done!");
list1.displayEntireTable();
}
public void createTable(int tableLength, int tableWidth) {
length = tableLength;
width = tableWidth;
this.newTable = new ArrayList();
for (int i = 0; i < tableWidth; i++) {
this.newTable.add(new ArrayList(tableLength));
}
}
public void displayRow(int row) {
System.out.println(this.newTable.get(row));
}
/**
* This function displays the column of the table. Still work which
* needs to be done here.
* #param column
*/
public void displayColumn(int column) {
if (this.newTable.size() >= column) {
for (int i = 0; i < this.newTable.size(); i++) {
// This doesn't work.
System.out.println(this.newTable.get(i).get(column));
}
}
}
public void displayEntireTable() {
for (int i = 0; i < this.newTable.size(); i++) {
System.out.println(this.newTable.get(i));
}
}
}
I'm suspicious that the problem may rely the lack of use in generics, which I'm not quite as familiar with yet as I would like to be. So my question to you, stackoverflow, is whether this data structure - an ArrayList of ArrayLists - is even possible, and if so, where lays my problem?
I think the problem is that you misunderstood the semantics of the new ArrayList(tableLength) call: it does not create an array list of tableLength elements; rather, it creates an ArrayList with the initial capacity enough to hold at least tableLength elements.
I am not sure what kind of elements you are planning to add to your ArrayList of ArrayLists, but here is one way to test your code that creates a two-dimensional ArrayList:
for (int i = 0; i < tableWidth; i++) {
ArrayList toAdd = new ArrayList(tableLength);
for (int j = 0; j != tableLength ; j++) {
toAdd.add(new Integer(i*tableLength +j));
}
this.newTable.add(toAdd);
}
Using Java 1.7 generics improvements:
import java.util.ArrayList;
import java.util.List;
public class Table {
private int length, width;
private List<List<String>> newTable;
public Table() {
this.length = this.width = 0;
}
/**
* Testing a few functions
*/
public static void main(String[] args) {
// Just testing a few functions.
Table list1 = new Table();
list1.createTable(4, 4);
list1.displayRow(1);
System.out.println("displayRow done!");
list1.displayColumn(1);
System.out.println("displayColumn done!");
list1.displayEntireTable();
System.out.println("displayEntireTable done!");
}
public void createTable(int tableLength, int tableWidth) {
length = tableLength;
width = tableWidth;
//by java 1.7 diamond feature, some generics can be hidden
this.newTable = new ArrayList<>();
for (int i = 0; i < tableWidth; i++) {
List<String> columns = new ArrayList<>();
for (int j = 0; j < tableLength; j++) {
columns.add(new String("test"));
} //added here
this.newTable.add(columns);
}
}
public void displayRow(int row) {
System.out.println(this.newTable.get(row));
}
/**
* This function displays the column of the table. Still work which
* needs to be done here.
* #param column
*/
public void displayColumn(int column) {
for (int i = 0; i < this.newTable.size(); i++) {
System.out.println("[" + this.newTable.get(i).get(column) + "]");
}
}
public void displayEntireTable() {
for (int i = 0; i < this.newTable.size(); i++) {
System.out.println(this.newTable.get(i));
}
}
}
Sure it's possible, and I suspect your issues are related to generics, actually -- if you don't use generics, you'll have to do a bunch of casts, which may appear to you as if it just doesn't work.
I'd write this as something like
List<List<Object>> table;
and then I'd add rows by doing table.add(new ArrayList<Object>()), and access elements with table.get(i).get(j).
First of all, what is your real problem? You don't add any data into the inner ArrayLists, so they are empty.
On the other hand, it is better if you create an object for a row, and store these objects in an arraylist.
Change your code that doesn't work to:
System.out.println(((ArrayList) this.newTable.get(i)).get(column));
ArrayList in ArrayList is certainly possibly.
And it is certainly not generics that prohibits you.
Generics is only a compile time check for mistakes and has nothing to do with it. You can complete leave it out, not advised as the probability for class cast exceptions due too mistakes is far larger.
Explanation. The compiler don't knows your ArrayList contains an ArrayList so it doesn't recognize the get method as it trys to invoke it on Object and not ArrayList. So the solution is to cast it if you wan't to use it without generics. However I would recomend to use generics and define your List like this.
private List<List<String> newTable;
Notice how I used List and not ArrayList. Typically your left hand assignment contains an Interface and the right hand an concrete class like ArrayList.