I wanted to use a String list as a source of various options in jComboBox in Java. Can you tell which method to use
Thanks
See Below for my answer... take into account this is untested and merely an example.
You need to create a custom implmentation of ComboBoxModel like Chandru said,
Then set the ComboBoxModel on your JComboBox using the setModel() method and add elements using ((CustomComboBoxModel<String>)jComboBox.getModel()).add(listOfThings);
Something like this:
import java.util.List;
import javax.swing.ComboBoxModel;
/**
* Custom Implementation of {#code ComboBoxModel} to allow adding a list of
* elements to the list.
*/
public interface CustomComboBoxModel<T> extends ComboBoxModel {
void add(List<T> elementsToAdd);
List<T> getElements();
}
and then implement the interface using something like this:
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractListModel;
/**
* Default Implementation of CustomComboBoxModel - untested.
*/
public class DefaultCustomComboBoxModel<T> extends AbstractListModel implements CustomComboBoxModel<T> {
List<T> objects;
T selectedObject;
/**
* Constructs an empty DefaultCustomComboBoxModel object.
*/
public DefaultCustomComboBoxModel() {
objects = new ArrayList<T>();
}
/**
* Constructs a DefaultCustomComboBoxModel object initialized with
* an array of objects.
*
* #param items an array of Object objects
*/
public DefaultCustomComboBoxModel(final T items[]) {
objects = new ArrayList<T>();
int i, c;
for (i = 0, c = items.length; i < c; i++) {
objects.add(items[i]);
}
if (getSize() > 0) {
selectedObject = objects.get(0);
}
}
// implements javax.swing.ComboBoxModel
/**
* Set the value of the selected item. The selected item may be null.
* Make sure {#code anObject} is an instance of T otherwise a
* ClassCastException will be thrown.
* <p>
* #param anObject The combo box value or null for no selection.
*/
#Override
public void setSelectedItem(Object anObject) {
if ((selectedObject != null && !selectedObject.equals(anObject))
|| selectedObject == null && anObject != null) {
selectedObject = (T) anObject;
fireContentsChanged(this, -1, -1);
}
}
// implements javax.swing.ComboBoxModel
#Override
public T getSelectedItem() {
return selectedObject;
}
// implements javax.swing.ListModel
#Override
public int getSize() {
return objects.size();
}
// implements javax.swing.ListModel
#Override
public T getElementAt(int index) {
if (index >= 0 && index < objects.size()) {
return objects.get(index);
} else {
return null;
}
}
/**
* Returns the index-position of the specified object in the list.
*
* #param anObject
* #return an int representing the index position, where 0 is
* the first position
*/
public int getIndexOf(T anObject) {
return objects.indexOf(anObject);
}
// implements javax.swing.MutableComboBoxModel
public void addElement(T anObject) {
objects.add(anObject);
fireIntervalAdded(this, objects.size() - 1, objects.size() - 1);
if (objects.size() == 1 && selectedObject == null && anObject != null) {
setSelectedItem(anObject);
}
}
// implements javax.swing.MutableComboBoxModel
public void insertElementAt(T anObject, int index) {
objects.add(index, anObject);
fireIntervalAdded(this, index, index);
}
// implements javax.swing.MutableComboBoxModel
public void removeElementAt(int index) {
if (getElementAt(index) == selectedObject) {
if (index == 0) {
setSelectedItem(getSize() == 1 ? null : getElementAt(index + 1));
} else {
setSelectedItem(getElementAt(index - 1));
}
}
objects.remove(index);
fireIntervalRemoved(this, index, index);
}
// implements javax.swing.MutableComboBoxModel
public void removeElement(T anObject) {
int index = objects.indexOf(anObject);
if (index != -1) {
removeElementAt(index);
}
}
/**
* Empties the list.
*/
public void removeAllElements() {
if (objects.size() > 0) {
int firstIndex = 0;
int lastIndex = objects.size() - 1;
objects.clear();
selectedObject = null;
fireIntervalRemoved(this, firstIndex, lastIndex);
} else {
selectedObject = null;
}
}
#Override
public void add(List<T> elementsToAdd) {
objects.addAll(elementsToAdd);
fireContentsChanged(this, -1, -1);
}
#Override
public List<T> getElements() {
return objects;
}
}
Extend DefaultComboboxModel and create a method which takes a Collection and sets the items from that collection. Set this custom model as your combobox's model using setModel().
Here you have code which creates combo box from array of Strings, all you need to do is transform your list to an array.
String petStrings = ...;
//Create the combo box, select item at index 4.
//Indices start at 0, so 4 specifies the pig.
JComboBox petList = new JComboBox(petStrings.toArray());
The easiest way is:
comboBox.setModel(new DefaultComboBoxModel(list.toArray()));
I know it's an old post, but I wanted to make a small addition to edwardsmatt's DefaultCustomComboBoxModel. Don't forget to add this constructor:
public DefaultCustomComboBoxModel(List<T> list) {
objects = list;
if (getSize() > 0) {
selectedObject = objects.get(0);
}
}
so that the model can also be initialized with a list, e.g.
myCombo.setModel(new DefaultCustomComboBoxModel(myList));
If you use ((CustomComboBoxModel)myCombo.getModel()).add(myList) you'll need to explicitly set the selected item.
You can also do it like this:
DefaultTableModel modelTabele = (DefaultTableModel) tblOsobe.getModel();
modelTabele.addColumn("Ime");
modelTabele.addColumn("Prezime");
modelTabele.addColumn("Datum Rodjenja");
for (Osoba osoba : Liste.osobe) {
System.out.println("" + osoba);
Object[] podaci = new Object[3];
podaci[0] = osoba.getIme();
podaci[1] = osoba.getPrezime();
podaci[2] = osoba.getDatumRodjenja();
modelTabele.addRow(podaci);
}
This model has 3 columns and as many rows as there are in Liste.osobe list of strings.
Related
The bubble sort sorting in the driver class works fine but I make a new list and try to do insertion sort and it just doesn't sort the list. I was thinking it was something with the setSortBehavior method in the first Listing class but everything I've tried hasn't worked.
package strategydesignpattern;
import java.util.ArrayList;
public class Listing {
protected String title;
protected ArrayList<String> items;
protected SortBehavior theSortBehavior;
/**
* Creates a list with the indicated name
* #param title The title of the list
*/
public Listing(String title)
{
this.title = title;
this.items = new ArrayList<String>();
this.theSortBehavior = new BubbleSort();
}
/**
* Adds an item to the list
* #param item the item you want to add to the list
*/
public void add(String item)
{
items.add(item);
}
/**
* removes an item from the list
* #param item the item you want to remove from the list
*/
public void remove(String item)
{
items.remove(item);
}
/**
* a getter for the name of the list
* #return returns the title of the list
*/
public String getTitle()
{
return title;
}
/**
* sets the sort behavior to whatever is passed in
* #param sortBehavior gets the sort behavior, either insertion or bubble
*/
public void setSortBehavior(SortBehavior sortBehavior)
{
theSortBehavior = sortBehavior;
}
/**
*
* #return returns the sorted list of items
*/
public ArrayList<String> getSortedList()
{
return theSortBehavior.sort(items);
}
/**
*
* #return returns the unsorted list of items
*/
public ArrayList<String> getUnSortedList()
{
return items;
}
}
//////
package strategydesignpattern;
import java.util.ArrayList;
public interface SortBehavior {
public ArrayList<String> sort(ArrayList<String> data);
}
///
package strategydesignpattern;
import java.util.ArrayList;
public class BubbleSort implements SortBehavior{
public ArrayList<String> sort(ArrayList<String> data)
{
String temp;
boolean sorted = false;
while (!sorted) {
sorted = true;
for (int i = 0; i < data.size()-1; i++) {
if (data.get(i).compareTo(data.get(i + 1)) > 0) {
temp = data.get(i);
data.set(i, data.get(i + 1));
data.set(i + 1, temp);
sorted = false;
}
}
}
return data;
}
}
//
package strategydesignpattern;
import java.util.ArrayList;
public class InsertionSort implements SortBehavior{
public ArrayList<String> sort(ArrayList<String> data)
{
for (int j = 1; j < data.size(); j++) {
String current = data.get(j);
int i = j-1;
while ((i > -1) && ((data.get(i).compareTo(current)) == 1)) {
data.set(i+1, data.get(i));
i--;
}
data.set(i+1, current);
}
return data;
}
}
////
package strategydesignpattern;
import java.util.ArrayList;
/**
* Creates lists of information, and displays the sorted versions of the lists
*/
public class ListDriver {
/**
* Creates a new ListDriver
*/
public ListDriver(){}
/**
* Main entryway to the program
* Creates the lists, and displays the sorted lists
*/
public void run() {
Listing shoppingList = new Listing("Grocery List");
shoppingList.add("Apples");
shoppingList.add("Peaches");
shoppingList.add("Cheese");
shoppingList.add("Crackers");
shoppingList.add("Chocolate");
shoppingList.add("Cherries");
shoppingList.add("Bananas");
shoppingList.add("Oranges");
ArrayList<String> sortedGroceryItems = shoppingList.getSortedList();
System.out.println(shoppingList.getTitle());
displayList(sortedGroceryItems);
Listing wishList = new Listing("Wish List");
wishList.setSortBehavior(new InsertionSort());
wishList.add("Bike");
wishList.add("Paddle Board");
wishList.add("Boat");
wishList.add("Truck");
wishList.add("Puzzle");
wishList.add("Monolopy");
wishList.add("Skipping Rope");
wishList.add("Cherry Tree");
ArrayList<String> sortedWishListItems = wishList.getSortedList();
System.out.println("\n" + wishList.getTitle());
displayList(sortedWishListItems);
}
/**
* Loops through and displays each item in the list items
* #param items list to display
*/
private void displayList(ArrayList<String> items){
for(String item : items){
System.out.println("- " + item);
}
}
public static void main(String[] args){
ListDriver driver = new ListDriver();
driver.run();
}
}
It appears that you have assumed the String.compareTo will return 1 to indicate a lexicographical ordering where the string the method is being invoked on follows the argument string. The Documenation states that the return value for String.compareTo is a positive integer to indicate this lexicographical ordering, not specifically 1.
I have try to debug your code. I find that (data.get(i).compareTo(current)) == 1) is not correct. According to the Java String API (https://docs.oracle.com/javase/10/docs/api/java/lang/String.html#compareTo(java.lang.String))
The result is a negative integer if this String object lexicographically precedes the argument string. The result is a positive integer if this String object lexicographically follows the argument string. The result is zero if the strings are equal; compareTo returns 0 exactly when the equals(Object) method would return true.
It says the result is a positive integer.
I am attempting to build a Priority Queue by modifying my previously implemented Queue that accepts generics. I create a class called Priority Queue (which accepts generics) that extends my Queue class (which accepts generics). The last class is the prime focus, Queue< T >. I push a customer in my tests, and when I receive that customer in my push method of Queue , I want to use it to compare its priority to another customer's priority in my Queue. Any suggestions on approaching this will be helpful, but my question is, how do I access the 3 fields of my object customer ( or val in push) from inside Queue ?
I have a test class that tests if my comparators work. I also have set up a test cases so that I can ensure that my priority queue works when I implement it.
My class for testing if my comparators work and if my Priority Queue works when implemented:
public class TestCustomer {
public static void main(String args[]) {
Customer customer1 = new Customer(3000, 20, 5);
Customer customer2 = new Customer(5000, 15, 7);
Customer customer3 = new Customer(5000, 20, 5);
Customer customer4 = new Customer(3000, 3, 5);
Customer customer5 = new Customer(3000, 3, 8);
// comparator test
Customer.WorthComparator worth = new Customer.WorthComparator();
Customer.LoyaltyComparator loyal = new Customer.LoyaltyComparator();
Customer.WorthPoliteComparator polite = new Customer.WorthPoliteComparator();
assert worth.compare(customer1, customer2) == -1;
assert worth.compare(customer2, customer3) == 0;
assert worth.compare(customer2, customer1) == 1;
assert loyal.compare(customer1, customer2) == 1;
assert loyal.compare(customer2, customer1) == -1;
assert loyal.compare(customer1, customer3) == 0;
assert polite.compare(customer3, customer2) == -1;
assert polite.compare(customer2, customer3) == 1;
assert polite.compare(customer1, customer2) == -1;
assert polite.compare(customer2, customer3) == 1;
assert polite.compare(customer1, customer4) == 0;
// priority queue test
PriorityQueue<Customer> pQueueW = new PriorityQueue<Customer>(worth);
PriorityQueue<Customer> pQueueL = new PriorityQueue<Customer>(loyal);
PriorityQueue<Customer> pQueueP = new PriorityQueue<Customer>(polite);
// push -- type T, pass in a val // judgement upon worth
//PUSH customers for Worth
pQueueW.push(customer1);
pQueueW.push(customer2);
pQueueW.push(customer4);
assert pQueueW.pop() == customer2;
//PUSH customers for Loyalty
pQueueL.push(customer1);
pQueueL.push(customer2);
pQueueL.push(customer3);
assert pQueueL.pop() == customer1;
//PUSH customers for Polite
pQueueP.push(customer2);
pQueueP.push(customer4);
pQueueP.push(customer5);
assert pQueueP.pop() == customer2;
assert pQueueP.pop() == customer5;
//
}
}
My Priority Queue class simply extends Queue and uses its push function. I will need to make a method to call to my pop in Queue:
import java.util.Comparator;
public class PriorityQueue<T> extends Queue<T>
{
Comparator<T> compare;
public PriorityQueue(Comparator<T> comp)
{
compare = comp;
}
//#Override
public void push(T val)
{
super.push(val); //right now this is just a normal Queue as it will do what its parent did.
}
My customer class has a constructor to create customers. This is also where I implement my different comparators to create an ordering of customers:
import java.util.Comparator;
public class Customer
{
int netWorth;
int yearsWithCompany;
int politeness;
public Customer(int netWorth,int yearsWithCompany,int politeness)
{
this.netWorth = netWorth;
this.yearsWithCompany = yearsWithCompany;
this.politeness = politeness;
}
/**
compares clients based on thier net worth
*/
public static class WorthComparator implements Comparator<Customer>
{
*/
public int compare(Customer c1, Customer c2)
{
int net1 = c1.netWorth;
int net2 = c2.netWorth;
if (net1 == net2) {
return 0;
}
else if (net1 < net2) {
return -1;
}
else {
return 1;
}
}
}
/**
compares clients based on thier loyalty
*/
public static class LoyaltyComparator implements Comparator<Customer>
{
/**
*/
public int compare(Customer c1, Customer c2)
{
int years1 = c1.yearsWithCompany;
int years2 = c2.yearsWithCompany;
if (years1 == years2) {
return 0;
}
else if (years1 < years2) {
return -1;
}
else {
return 1;
}
}
}
/**
compares clients based on thier net worth.
If there is a tie, politeness is used.
*/
public static class WorthPoliteComparator implements Comparator<Customer>
{
/**
*/
public int compare(Customer c1, Customer c2)
{
if (c1.netWorth == c2.netWorth)
{
if (c1.politeness < c2.politeness) {
return -1;
}
else if (c1.politeness > c2.politeness) {
return 1;
}
else {
return 0;
}
}
else if (c1.netWorth > c2.netWorth){
//int politeness = WorthComparator.compare(c1, c2);
//return politeness;
return 1;
}
else {
return -1 ;
}
}
}
}
My Queue class WAS implemented to function as a regular queue. I am now modifying it so that I can turn it into a Priority Queue. The Queue class is below:
public class Queue
{
public class QNode<T> {
private QNode<T> node;
private T val;
public QNode(QNode<T> node, T val) {
this.node = node;
this.val = val;
}
}
protected QNode<T> head;
protected QNode<T> rear;
protected QNode<T> temp;
public Queue()
{
head = null;
rear = null;
}
public void push(T val) // T = Customer type -- val is a customer
{
// if I wanted to get the contents out of val, which is a customer
// who has a net worth, years loyal, and politeness
// how would I access let's say, the netWorth from val?
// first node created
if (head == null && rear == null){
head = new QNode<T>(rear, val);
rear = head;
}
}
public T pop()
{
if (head == null){
throw new QueueUnderFlowException();
}
else if(head == rear) {
T temp_hold = head.val;
head = null;
rear = null;
return temp_hold;
}
else {
T oldN = head.val;
this.head = this.head.node;
return oldN;
}
}
/**
returns true if the queue is empty
*/
public boolean isEmpty()
{
if (head == null) {
return true;
}
else {
return false;
}
}
}
If your Queue is generic, you can't refer to properties of Customer directly. You'll have to make them accessible via some interface/baseclass the Queue knows about. Since the Queue doesn't really care about the customer's net worth, but about sorting between different customers, there are two classic ways of doing this.
First, you could make the Queue handle Comparable objects:
public class Queue<T extends Comparable<T>> {
// code...
and make the Customer comparable by its networth:
public class Customer implements Comparable<Customer> {
#Override
public int compareTo(Customer other) {
return Integer.compare(netWorth, other.netWorth);
}
// rest of the code...
}
or, if you don't want to impose this natural ordering on the Customer class, the Queue class can take a Comparator, such as Comparator.comparingInt(Customer::getNetWorth()) when its constructed.
Second programming class
So we have been tasked with a linked list, building each method from scratch.
Well I started on this day before yesterday and had a null pointer exception, I figured id iron it out later and continued.
Well after cutting my program down to nothing to find the culprit im left with code that SHOULD work as its copied from our lab (that worked).
If you guys think you can figure out why im getting a null pointer exception on my add method id greatly appreciate it and see if im doing the second constructor correctly. If I can get SOME traction on this to get started it would go allot easier but as is I cant even begin.
You will notice allot of blank methods, ill get to them once I can get my constructor + add method working
My code:
import java.util.Collection;
import java.util.Iterator;
/**
* Created by hhhh on 11/2/2014.
*/
public class Lset<R> implements Set151Interface<R> {
private Node head;
private int length;
/**In the first (following) constructor im trying to re use code and call my clear method.
*Should save space and make code look cleaner.
*/
public Lset(){
clear();
}
public Lset(Collection<? extends R> list){
this();
for (R object : list) {
add(object);
}
}
/**
* Copied from Lab7, this add method checks to see if there are more nodes than just the head.
* After the check if false, creates a new node and adds it to the end of the list.
* #param entry
* #return
*/
#Override
public boolean add(R entry) {
Node newNode = new Node(entry);
// empty list is handled differently from a non-empty list
if (head.next == null) {
head = newNode;
} else {
Node lastNode = getNodeAt(length - 1);
lastNode.next = newNode;
}
length++;
return true;
}
#Override
public void clear() {
this.length = 0;
this.head = null;
}
#Override
public boolean contains(Object o) {
return false;
}
#Override
public Iterator<R> iterator() {
return null;
}
#Override
public boolean containsAll(Collection<?> c) {
return false;
}
#Override
public boolean isEmpty() {
return false;
}
#Override
public boolean remove(Object o) {
return false;
}
#Override
public boolean addAll(Collection<? extends R> c) {
return false;
}
#Override
public boolean removeAll(Collection<?> c) {
return false;
}
#Override
public boolean retainAll(Collection<?> c) {
return false;
}
#Override
public int size() {
return length;
}
#Override
public Object[] toArray() {
return null;
}
#Override
public <T> T[] toArray(T[] array) {
return null;
}
/**
* Code used in Lab 7, getNodeAt uses the length field and starts at head to traverse array and arrive at the
* position desired.
* #param position
* #return
*/
private Node getNodeAt(int position) {
assert !isEmpty() && (position >= 0) && position < length;
Node cNode = head;
for (int i = 0; i < position; i++)
cNode = cNode.next;
assert cNode != null;
return cNode;
}
public String toString(){
String arrayString = "<";
for(int i = 0; i < length; i++){
String two = getNodeAt(i).toString();
arrayString += two;
if(i <= (length - 2)){
two = ", ";
arrayString += two;
}
}
arrayString += ">";
return arrayString;
}
//TODO comment better
public class Node {
/** Reference to the data */
public R data;
/** Reference to the next node is in the list */
public Node next;
/**
* Sets the data for this node.
* #param data data to be carried by this node.
*/
public Node(R data) {
this.data = data;
this.next = null;
}
/**
* Sets the data for the node and assigns the next node in the list.
* #param data data to be carried by this node.
* #param nextNode next node in the list.
*/
public Node(R data, Node nextNode) {
this.data = data;
this.next = nextNode;
}
/**
* Returns just the data portion of the node.
* #return The data portion of the node.
*/
public R getData() {
return this.data;
}
/**
* Modified just the data portion of the node.
* #param data new data to be contained within the node.
*/
public void setData(R data) {
this.data = data;
}
/**
* What node does this node point to.
* #return the node that this node points to or null if it does not
* point anywhere.
*/
public Node getNextNode() {
return this.next;
}
/**
* Change the node that this node points to.
* #param nextNode a new node for this node to point to.
*/
public void setNextNode(Node nextNode) {
this.next = nextNode;
}
/**
* Display the state of just the data portion of the node.
*/
public String toString() {
return this.data.toString();
}
}
}
This is the method in main thats killing it
private void testConstruction() {
System.out.println("\nTesting Constructor");
System.out.print("----------------------------------------");
System.out.println("----------------------------------------");
Set151Interface s = makeSet();
//added
s.add("Butterfinger");
test(s.size() == 0,
"size() should return 0: " + s.size());
test(s.toString().equals("<>"),
"toString returns \"<>\": " + s.toString());
ArrayList<String> temp = new ArrayList<String>();
temp.add("Butterfinger");
temp.add("Milky Way");
temp.add("Kit Kat");
temp.add("Three Muskateers");
Set151Interface s3 = makeSet(temp);
test(s3.size() == 4,
"size should return 4: " + s3.size());
test(s3.toString().equals("<Butterfinger, Milky Way, Kit Kat, Three Muskateers>"),
"toString should return\n "+
"\"<Butterfinger, Milky Way, Kit Kat, Three Muskateers>\":\n "
+ s3.toString());
}
as soon as butterfinger attempts to get added I get null pointer exception pointing to this line
if (head.next == null) {
You just declared private Node head; and it doesnt takes any value assigned . so the compiler throws NPE
Thanks for the help guys, I figured it out :).
On day one I had edited my driver (and forgot) once I re copied the driver everything works (so far) thanks again guys!
Looking for a insertion order collection that also allows efficient querying and subset views of positions (like sublist). Seems the most straightforward option for this would be to take the linked list approach of List, embed the nodes as map values and expose part or all of the list interface on the class.
Would someone bitch to Oracle about this? Having NavigableMap/Set added for sorted maps and sets and not having the far more common insertion order equivalent...
edit: please don't suggest LinkedHashSet - it doesn't have any way to query the position or to do a relative subset.
you mean like java.util.LinkedHashSet:
Hash table and linked list implementation of the Set interface, with
predictable iteration order. This implementation differs from HashSet
in that it maintains a doubly-linked list running through all of its
entries. This linked list defines the iteration ordering, which is the
order in which elements were inserted into the set (insertion-order).
Note that insertion order is not affected if an element is re-inserted
into the set. (An element e is reinserted into a set s if s.add(e) is
invoked when s.contains(e) would return true immediately prior to the
invocation.)
edit2: New final version
Here is a version only for sets with slightly adjusted function (divided into two, no longer accepts null as 'beginning of the map') that probably has less bugs
public class LinkedSet<E> implements Set<E> {
private LinkedHashMap<E, Integer> m = new LinkedHashMap<E, Integer>();
private int monoticallyIncreasing;
/**
* Returns true if the value target was added before (exclusive)
* limitElem in insertion order.
*
* If target or limit are not present on the set this method returns false
*
* #param limitElem a E that may be a element of the set or not.
* #return if target was added before limit (can be reset by removing and
* re-adding the target, that changes iteration order).
*/
public boolean containsBefore(E target, E limitElem) {
if (isEmpty()) {
return false;
}
Integer targetN = m.get(target);
if (targetN == null) {
return false;
}
Integer highN = m.get(limitElem);
if (highN == null) {
return false;
}
return targetN < highN;
}
/**
* Returns true if the value target was added after (exclusive)
* previousElem in insertion order.
*
* If target or previous are not present on the set this method returns false
*
* #param previousElem a E that may be a element of the set or not.
* #return if target was added before previous (can be reset by removing and
* re-adding the target, that changes iteration order).
*/
public boolean containsAfter(E target, E previousElem) {
if (isEmpty()) {
return false;
}
Integer targetN = m.get(target);
if (targetN == null) {
return false;
}
Integer low = m.get(previousElem);
if (low == null) {
return false;
}
return low < targetN;
}
#Override
public boolean add(E e) {
Integer pos = m.get(e);
if (pos == null) {
m.put(e, monoticallyIncreasing++);
return true;
}
return false;
}
#Override
public int size() {
return m.size();
}
#Override
public boolean isEmpty() {
return m.isEmpty();
}
#Override
public boolean contains(Object o) {
return m.containsKey(o);
}
#Override
public Object[] toArray() {
Object[] result = new Object[size()];
int i = 0;
for (E e : this) {
result[i++] = e;
}
return result;
}
#Override
#SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
int size = size();
if (a.length < size) {
a = (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);
}
int i = 0;
Object[] result = a;
for (E e : this) {
result[i++] = e;
}
if (a.length > size) {
//peculiar toArray contract where it doesn't care about the rest
a[size] = null;
}
return a;
}
#Override
public boolean remove(Object o) {
return m.remove(o) != null;
}
#Override
public boolean addAll(Collection<? extends E> c) {
boolean changed = false;
for (E e : c) {
changed |= add(e);
}
return changed;
}
#Override
public boolean containsAll(Collection<?> c) {
return m.keySet().containsAll(c);
}
#Override
public boolean retainAll(Collection<?> c) {
return m.keySet().retainAll(c);
}
#Override
public boolean removeAll(Collection<?> c) {
return m.keySet().removeAll(c);
}
#Override
public void clear() {
m.clear();
}
#Override
public Iterator<E> iterator() {
return m.keySet().iterator();
}
}
I created a multidimensional array called current_map.
I am trying to access current_map:
current_map[0][1]
However I receive the error:
error: array required, but String found
Here is my code for your viewing pleasure
import java.util.*;
import java.util.Map.Entry;
import java.util.ArrayList;
public class TestApp {
private ArrayList<String[]> current_map = new ArrayList<String[]>();
public TestApp() {
current_map.add(new String[] { "0","0","0" });
current_map.add(new String[] { "0","Q","0" });
current_map.add(new String[] { "0","0","0" });
}
public String getValue(int X,int Y){
String[] obj_map = current_map.toArray(new String[current_map.size()]);
return obj_map[X][Y]; // for example, getValue(2,2), should give "Q"
}
}
How can I stop this issue?
You can do something like this:
import java.util.*;
import java.util.Map.Entry;
import java.util.ArrayList;
public class TestApp {
private ArrayList<String[]> current_map = new ArrayList<String[]>();
public TestApp() {
current_map.add(new String[] { "0","0","0" });
current_map.add(new String[] { "0","Q","0" });
current_map.add(new String[] { "0","0","0" });
}
public String getValue(int X,int Y){
return current_map.get(Y)[X]; // for example, getValue(2,2), should give "Q"
}
public static void main(String[] args) {
TestApp ta = new TestApp();
System.out.println(ta.getValue(1, 1));
}
}
Note that in Java array indexes are 0-based, so 2nd row, 2nd column is represented with (1, 1), not (2, 2).
Hope this helps.
Unless there's compelling reason to do a full copy on every get command, you should use your existing structure.
public String getValue(int X, int Y)
{
return current_map.get(X)[Y];
}
You have said obj_map is a String[], but in the very next line you treat it as a 2D array.
What you have is not really a true multi-dimension representation as the way you access different dimensions is not consistent. Its semantics but to call it a true multi-dimensional (including symantics) you need something like this (Please refer this for the source of this code. I am not the owner of this code.)
import java.util.ArrayList;
public class ArrayList2d<Type>
{
ArrayList<ArrayList<Type>> array;
public ArrayList2d()
{
array = new ArrayList<ArrayList<Type>>();
}
/**
* ensures a minimum capacity of num rows. Note that this does not guarantee
* that there are that many rows.
*
* #param num
*/
public void ensureCapacity(int num)
{
array.ensureCapacity(num);
}
/**
* Ensures that the given row has at least the given capacity. Note that
* this method will also ensure that getNumRows() >= row
*
* #param row
* #param num
*/
public void ensureCapacity(int row, int num)
{
ensureCapacity(row);
while (row < getNumRows())
{
array.add(new ArrayList<Type>());
}
array.get(row).ensureCapacity(num);
}
/**
* Adds an item at the end of the specified row. This will guarantee that at least row rows exist.
*/
public void add(Type data, int row)
{
ensureCapacity(row);
while(row >= getNumRows())
{
array.add(new ArrayList<Type>());
}
array.get(row).add(data);
}
public Type get(int row, int col)
{
return array.get(row).get(col);
}
public void set(int row, int col, Type data)
{
array.get(row).set(col,data);
}
public void remove(int row, int col)
{
array.get(row).remove(col);
}
public boolean contains(Type data)
{
for (int i = 0; i < array.size(); i++)
{
if (array.get(i).contains(data))
{
return true;
}
}
return false;
}
public int getNumRows()
{
return array.size();
}
public int getNumCols(int row)
{
return array.get(row).size();
}
}