Multiple values in one ArrayList key - java

I'm trying to put multiple values in one arraylist key, but instead I get an error:
Class:
public class BestellenWindow extends javax.swing.JFrame {
private ArrayList<String> bestelling = new ArrayList<String>();
public BestellenWindow() {
initComponents();
}
Action performed:
private void BestellenbuttonActionPerformed(java.awt.event.ActionEvent evt)
{
bestelling.add(Barcodetext.getText(), Aantaltext.getText());
System.out.println(bestelling.get(0));
}
error:
no suitable method found for add(java.lang.String,java.lang.String)
method java.util.ArrayList.add(int,java.lang.String) is not applicable
(actual argument java.lang.String cannot be converted to int by method invocation conversion)
method java.util.ArrayList.add(java.lang.String) is not applicable

An ArrayList is just a list. It doesn't have a "key". If you want to store objects by key, use an implementation of interface Map (for example HashMap) instead of a List.
But, a normal Map can store only one value per key. If you want to store multiple values, you can use a Map<K, List<V>> (where K is the key type and V the value type), or you could use for example Multimap from Google Guava.
But there's also another, perhaps better solution. Create a new class to hold the barcode and aantal, and store instances of that class in your ArrayList. For example:
public class Bestelling {
private String barcode;
private int aantal;
public Bestelling(String barcode, int aantal) {
this.barcode = barcode;
this.aantal = aantal;
}
public String getBarcode() {
return barcode;
}
public int getAantal() {
return aantal;
}
}
// Later:
Bestelling b = new Bestelling(Barcodetext.getText(),
Integer.parseInt(Aantaltext.getText()));
bestelling.add(b);

In Java there are two elements.
1. List Interface : This does not hold any key. It has the collection of the values. You can add one by one by add(value) method.
2. Map : This holds one key for a set of value.
List<String> userName = new ArrayList<String>();
userName.add("Jesper");
userName.add("Mafue");
Map<Long,String> userMap = new HashMap<Long,String>();
userMap.put(1l,"Jesper");
userMap.put(2l,"Mafue");
From map you can retrieve the values by providing key.

You are trying to invoke the method
list.add(int index, String value)
that it is used to insert an element at a specific position.
If this is what you actually want to do then I guess that Barcodetext should contain a string that is a number, so you need to convert it to an int with
Integer.parseInt(Barcodetext.getText())
If instead you want to add multiple values just call the method twice:
bestelling.add(Barcodetext.getText());
bestelling.add(Aantaltext.getText());

Use either:
bestelling.add(...);
bestelling.add(...);
...
or
bestelling.addAll(Arrays.asList(..., ...));

Related

Building a Sort object based on Map<Enum, Enum>

I would like to build a Sort object based on Map<Column, Direction>. I have a problem with the fact that the Sort class only has a private constructor, it just has to be created by the static method by() or and(), therefore I have a problem with initialising the sort object with the first element from the map.
private Sort buildSort(Map<WorklistColumn, Direction> columnsDirectionsmap){
Sort sort = by("wartość inicjalna której nie chcemy", Direction.Ascending);
for (Map.Entry<WorklistColumn, Direction> columnWithDirection : columnsDirectionsmap.entrySet()) {
sort.and(columnWithDirection.getKey().toString(), columnWithDirection.getValue());
}
return sort;
}
public class Sort {
private List<Column> columns = new ArrayList();
private Sort() {
}
public static Sort by(String column) {
return (new Sort()).and(column);
}
public static Sort by(String column, Direction direction) {
return (new Sort()).and(column, direction);
}
public Sort and(String name) {
this.columns.add(new Column(name));
return this;
}
public Sort and(String name, Direction direction) {
this.columns.add(new Column(name, direction));
return this;
}
Build a Sort object from a map
I think the question is about the fact that to fully configure a Sort object from your map, you need to use the first map entry in conjunction with Sort.by(), and then use all the other entries in conjunction with Sort.and(). That is, the first entry requires different handling than the rest.
There are lots of ways of dealing with that, but the one I'm going to suggest is to work directly with the iterator of the map's entry set. Something like this:
private Sort buildSort(Map<WorklistColumn, Direction> columnsDirectionsMap) {
if (columnsDirectionsMap.isEmpty()) {
throw new NoCriteriaException(); // or whatever
}
Iterator<Map.Entry<WorklistColumn, Direction>> criterionIterator =
columnsDirectionsMap.entrySet().iterator();
Map.Entry<WorklistColumn, Direction> criterion = criterionIterator.next();
Sort sort = Sort.by(criterion.key().toString(), criterion.value());
while (criterionIterator.hasNext()) {
criterion = criterionIterator.next();
sort.and(criterion.key().toString(), criterion.value());
}
return sort;
}
Do note that depending on the Map implementation involved, the order of the entries may not be easily predictable. I assume that you need control of that order for this approach to work as desired, so it's on you to choose a Map implementation that provides that. A LinkedHashMap might be suitable, for example, but probably not a HashMap.

Creating a new Set everytime a method is called

I have a map that should contain relations from an integer a to an integer b. Integer b should be in a Set. Relations from integer a to integer b can be added using the add method. To create such a relation, I have to create a new Set (to contain b) everytime the add method is called. How should I do this? I think I know how to do this with arrays since they support names containing variables, but sets don't.
public class intRelImplementation extends intRel {
protected final Map<Integer, Set<Integer>> connection;
public intRelImplementation (final int n) {
super(n);
connection = new HashMap<>();
}
#Override
public void add(int a, int b) {
// I have to create a new Set everytime the Add method is called.
// The Set should contain the Integer b, and this set should then be
// placed into the Map: Map<a, Set<b>>.
Set<Integer> setInMap = new HashSet<>(); //not correct obviously
Set setInMap2 = new HashSet(setInMap);
}
Suppose you call add(4,5) and then add(4,6).
If the result is that your map now contains 4 -> {5,6} (that is, the key 4 links to a set containing 5 and 6), then what you are making is a multi-valued map.
A way to add into a multi-valued map is something like this:
public void add(int a, int b) {
Set<Integer> values = connection.get(a);
if (values==null) {
values = new HashSet<Integer>();
connection.put(a, values);
}
values.add(b);
}
That is, get the set associated with the key a.
If there isn't one, create one and add it to the map.
Add your value b to the set.
Just add a new Set, if there isn't already a mapping for a in the Map and then add the value to the Set in the Map (whether it was just added or previously in the map):
connection.computeIfAbsent(a, k -> new HashSet<Integer>()).add(b);
I think this is what you're looking for
public class intRelImplementation extends intRel {
protected final Map<Integer, Set<Integer>> connection;
public intRelImplementation (final int n) {
super(n);
connection = new HashMap<>();
}
#Override
public void add(int key, int val) {
if(!connection.containsKey(key)){
connection.put(key, new HashSet<>());
}
connection.get(key).add(val);
}
...
}
!connection.containsKey(key) will check if the HashMap contains the key mapping. If it doesnt, it will add an mapped entry for {key, HashSet} where HashSet is an empty HashSet<Integer>
connection.get(key) will return the HashSet<Integer> associated to the key in the HashMap.
.add(val) will now add the value to the HashSet<Integer>
This guarantees that a hashset is created if the key doesnt exist, and then it adds the value to the set owned by the key

Sorting a list with objects?

In the contacts class (implements actionListener) I have a JList that contains objects (elements from a file). There are sorting buttons, each button has an actionListener
by firstname by last name by city The sorting is done by the elements of objects.
the user should give the first and last name and city for a contact. How to do the sorting ??
And to put those into the list I used this code:
Map<String, contacts> ma = readFromFile();
for (Map.Entry<String, contacts> entry : ma.entrySet()) {
contacts c = (contacts) entry.getValue();
d.addElement(c.getLastName() + "" + c.getFirstName() + "" + c.getCity());
}
How to do the sorting ?? plz help
Instead of JList<String>, create a JList<contacts>
Implement class ContactsRenderer extends JLabel implements ListCellRenderer.
See java doc for more details: http://docs.oracle.com/javase/7/docs/api/javax/swing/JList.html
Implement your custom list data model:
public class ContactsModel extends AbstractListModel<contacts>() {
private final List<contacts> backingList = ArrayList<contacts>;
public ContactsModel(Map<String, contacts> ma) {
//populate backing list here from your map
}
public int getSize() {
return backingList.size();
}
public contacts getElementAt(int index) {
return backingList.get(index);
}
};
Add a sort method to your model:
public void sort(Comparator<contacts> comparator) {
Collections.sort(backingList, comparator);
fireContentsChanged(this, 0, backingList.size());
}
Implement comparators for every sort use case:
public class LastNameAscendingComparator implements Comparator<contacts> {
#Override
public int compare(contacts c1, contacts c2){
return c1.getLastName().compareTo(c2.getLastName());
}
}
Finally call your model.sort() with a corresponding comparator
In java you can sort a list like so:
Collections.sort(yourListOfContacts, new Comparator<Contacts>(){
#Override
public int compare(Contacts obj1, Contacts obj2){
obj1.getFirstName().compareTo(obj2.getFirstName());
}
});
Notice that the return type of the compare function is an integer. This integer tells the sorting algorithm which one of the two should come first. Note that a -1 means the first element is "less" than the second, a 0 means that they are the same, and a 1 means that the first element is "greater" than the second. So, to reverse the order, you would use: obj2.getFirstName().compareTo(obj1.getFirstName()); or, you could just multiply by -1.
The other fields you want to sort by will follow the same sort of pattern, this is just an example.
In Java8 you can sort a list like this:
Collections.sort(contactList, (contact1, contact2)
-> contact1.getName().compareTo(contact2.getName()));

Java, get all variable values of a class

So I have a class called Test:
public class Test{
protected String name = "boy";
protected String mainAttack = "one";
protected String secAttack = "two";
protected String mainType"three";
protected String typeSpeak = "no spoken word in super class";
//Somehow put all the class variables in an Array of some sort
String[] allStrings = ??(all class' strings);
//(and if you feel challenged, put in ArrayList without type declared.
//So I could put in, not only Strings, but also ints etc.)
public void Tester(){
//Somehow loop through array(list) and print values (for-loop?)
}
}
As you can see, I want to put all the class variables in an Array or ArrayList (or something similar) automatically.
And next I want to be able to loop through the array and print/get the values.
Preferably using an enhanced-for loop.
As other said, don't do this. But this is how:
Class<?> cl = this.getClass();
List<Object> allObjects = new ArrayList<Object>();
for (java.lang.reflect.Field f: cl.getDeclaredFields())
{
f.setAccessible(true);
try
{
Object o = f.get(this);
allObjects.add(o);
}
catch (Exception e)
{
...
}
}
for (Object o: allObjects)
System.out.println(o);
If you really really need do this you need to use Reflection.
However a much better approach would be to store the values in a Map (probably a HashMap) and then you can query/set/etc them from that easily.
You can use Map or Hashmap to store variables and its values instead of Array or Arraylist
HashMap is an object that stores both “key/value” as a pairs. In this article, we show you how to create a HashMap instance and iterates the HashMap data.
Why not use a HashMap for the values and iterate through that?
Iterate through a HashMap
Do this.
String threeEleves = "sky";
String sevenDwarves = "stone";
String nineMortal = "die";
String oneRing[] = new String[] // <<< This
{
threeElves,
sevenDwarves,
nineMortal
}
or do this
// in some class.
public void process(final String... varArgs)
{
for (String current : varArgs)
{
}
}
String one = "noodles";
String two = "get";
String three = "in";
String four = "my";
String five = "belly";
process (one, two, three, four, five);

Nested RepeatingGrps within Java Design Issue

EDIT: I have two Objects I must map one to the other. The problem is that the attributes don't exactly match up. The object coming in I am mapping from is flat has a bunch of getters and setters. All very nice and easy to work with.
I have to map this to a an Object which has somewhat of a different structure, within Groups such as SecAltIDGrp[] and attritubes such as those below. Which is set using
ObjectToMapTo.setSecAltIDGrp(SecAltIDGrp[])
I have a few repeating groups which I must map with values from a getter from the flat object the problem is this. The object to be mapped to has Array[]s of Grps which must be populated by various different getters from the flat object. I cannot think of a clean way to do this.
For instance, I have a code an array of comments which has the following structure.
public SecAltIDGrp[] populateComments(int NoComments)
{
SecAltIDGrp[] x = new SecAltIDGrp[NoComments];
for(int i; i < NoComments; i++)
{
x[i].setAltID(obj.getVal);
x[i].setAltIDSource(arg0, arg1);
}
}
however each element of the array the is populated by a different getter from the flat object...
I cannot thing a nice of doing this bar inserting a if statement within the array and passing in the object as a parameter. This is rather horrific coding.
I am supposed to do this for a number of such groups. With some of the array element setters requiring arrays themselves.
Instead of using Array, try using HashMaps, which will help you pass/store the objects more easily.
If you are not really interested with the hashmap keys, then you can simply use ArrayList.
The HashMap will store the require group, along with the key. The key here will be similar to the array Index, you were planning to use.
public HashMap< Integer , SecAltIDGrp > populateComments( int NoComments )
{
HashMap< Integer , SecAltIDGrp > hmSec = new HashMap< Integer , SecAltIDGrp >();
for(int i; i < NoComments; i++)
{
SecAltIDGrp x = new SecAltIDGrp();
x.setAltID(obj.getVal);
x.setAltIDSource(arg0, arg1);
hmSec.put( i , x );
}
return hmSec;
}
public class SecAltIDGrp{
String altId = "";
String altIdSource = "";
public void setAltIDSource( String altIDSource )
{
this.altIdSource = altIDSource;
}
public void setAltID( String altId )
{
this.altId = altID;
}
}
Make sure the getters and setters will also have the appropriate parameters to satisfy the generics to prevent any warnings during compilation.
public class ObjectToMapTo
{
private HashMap< Integer , SecAltIDGrp > hmPrivGrp = new HashMap< Integer,SecAltIDGrp >();
public void setSecAltIDGrp( HashMap< Integer , SecAltIDGrp > hmSecAltIDGrp)
{
this.hmPrivGrp = hmSecAltIDGrp;
}
}
this is how you set the particular group. store the hashmap instead of an array.
ObjectToMapTo.setSecAltIDGrp( hmSec );
You will be able to iterate through the hashmap and be able to retrieve individual SecAltIDGrp
Some stuff to read up:
http://www.javadeveloper.co.in/java-example/java-hashmap-example.html

Categories