I would like to populate ComboBox in Java, but:
when I use array of strings, I must define the size of array before (this is disadvantage),
when I would like to use ArrayList, I cant have empty items with null values or I cant skip ids:
ArrayList<String> a = new ArrayList<String>();
a.add(0, "hahah");
a.add(1, "bleeeee");
a.add(5, "cleeeee"); //this makes an error, when I change index to 2, it works
JComboBox supplierComboBox = new JComboBox(a.toArray());
My array is for example:
[1] => "dog",
[5] => "mouse",
[8] => "cat".
(some ids missing).
THX.
You can't have an index of 5 without having indexes of 2, 3, and 4 as well. Java will either throw an exception at this, or it will silently fill all of the skipped indexes with null values. So just add values at 2, 3, and 4 and it should work. Make sure that there are no other skipped indexes as well.
To remove all the null values in a List, try this code:
public class RemoveNullValues {
private ArrayList<String> test = new ArrayList<String>();
public RemoveNullValues() {
test.add("0");
test.add(null);
test.add("1");
test.add(null);
test.add(null);
test.add("2");
test.add("3");
test.add("4");
test.add(null);
test.add("5");
System.out.println("Before: " + test);
//Java 7 and below method:
test.removeAll(Collections.singleton(null));
//Java 8+ method:
test.removeIf(Objects::isNull);
System.out.println("After: " + test);
}
public static void main(String[] args) {
new RemoveNullValues();
}
}
You can instantiate a combobox without children
JComboBox supplierComboBox = new JComboBox();
and then add the children in a for cycle:
ArrayList<String> a = new ArrayList<String>();
a.add("hahah");
a.add("bleeeee");
a.add("cleeeee");
for (String value : a) {
supplierComboBox.addItem(value); // you can put every kind of object in "addItem"
}
Some examples (if you need the id field):
Using Map.Entry
ArrayList<Map.Entry<Integer, String>> a = new ArrayList<Map.Entry<Integer, String>>();
a.add(new AbstractMap.SimpleEntry<Integer, String>(0, "hahah"));
a.add(new AbstractMap.SimpleEntry<Integer, String>(1, "bleeeee"));
a.add(new AbstractMap.SimpleEntry<Integer, String>(5, "cleeeee"));
for (Map.Entry<Integer, String> value : a) {
supplierComboBox.addItem(value);
}
Using MyClass:
public class MyClass{
private Integer id;
private String value;
public MyClass(Integer id, String value) {
this.id = id;
this.value= value;
}
// Getters & Setters
}
and then:
ArrayList<MyClass> a = new ArrayList<MyClass>();
a.add(new MyClass(0, "hahah"));
a.add(new MyClass(1, "bleeeee"));
a.add(new MyClass(5, "cleeeee"));
for (MyClass value : a) {
supplierComboBox.addItem(value);
}
Related
I have two arraylists of objects, I want to know which strings are unique to arraylist 1, and which strings are unique to arraylist 2. What I have come up with is the forloop below, which I have to implement twice, reversing the positions of the arraylists. I'm hopeful someone can suggest a more elegant way to do this.
Per request, a bunch more stuff I guess I wrongfully assumed was implied in the code-snippet itself. And the output this produces is:
grape doesn't exist in second arrayList
pineapple doesn't exist in first arrayList
Works great, everything is great, but, per above, I'm hopeful someone with more knowledge of streams/java in general can provide a better solution than just running my stream twice, with the inputs reversed.
import java.util.ArrayList;
public class CompareTwoArrays {
ArrayList<MyCustomObject> firstArrayListOfObjects = new ArrayList<>();
ArrayList<MyCustomObject> secondArrayListOfObjects = new ArrayList<>();
public void superSpecificExampleMethod() {
firstArrayListOfObjects.add(new MyCustomObject(1, 1, "apple"));
firstArrayListOfObjects.add(new MyCustomObject(1, 1, "orange"));
firstArrayListOfObjects.add(new MyCustomObject(1, 1, "banana"));
firstArrayListOfObjects.add(new MyCustomObject(1, 1, "grape"));
secondArrayListOfObjects.add(new MyCustomObject(1, 1, "apple"));
secondArrayListOfObjects.add(new MyCustomObject(1, 1, "pineapple"));
secondArrayListOfObjects.add(new MyCustomObject(1, 1, "orange"));
secondArrayListOfObjects.add(new MyCustomObject(1, 1, "banana"));
for (MyCustomObject object : firstArrayListOfObjects) {
if (!secondArrayListOfObjects.stream().map(MyCustomObject::getString).filter(object.getString()::equals).findFirst().isPresent()) {
System.out.println(object.getString() + " doesn't exist in second arrayList");
}
}
for (MyCustomObject object : secondArrayListOfObjects) {
if (!firstArrayListOfObjects.stream().map(MyCustomObject::getString).filter(object.getString()::equals).findFirst().isPresent()) {
System.out.println(object.getString() + " doesn't exist in first arrayList");
}
}
}
}
class MyCustomObject {
private int randomIntOne;
private int randomIntTwo;
private String string;
public MyCustomObject(int randomIntOne, int randomIntTwo, String string) {
this.randomIntOne = randomIntOne;
this.randomIntTwo = randomIntTwo;
this.string = string;
}
public String getString() {
return string;
}
}
Assuming there are two array lists of objects MyObject containing strings:
List<MyObject> listOne = new ArrayList<>(Arrays.asList(
new MyObject("aaa"), new MyObject("bbb"), new MyObject("ccc"), new MyObject("ddd")
));
List<MyObject> listTwo = new ArrayList<>(Arrays.asList(
new MyObject("fff"), new MyObject("bbb"), new MyObject("ggg"), new MyObject("ddd")
));
To find "unique" objects in listOne that is those which are not available in listTwo there are several ways:
Use List::removeAll providing that the methods equals and hashCode are properly implemented in this class
removeAll should be applied to a copy of listOne
List<MyObject> diffOneMinusTwo = new ArrayList<>(listOne); // copy
diffOneMinusTwo.removeAll(listTwo); // ["aaa", "ccc"]
Use List::removeIf accepting a predicate and using a set of the strings contained in the objects of listTwo:
Set<String> listTwoStrings = listTwo
.stream()
.map(MyObject::getString)
.collect(Collectors.toSet);
List<MyObject> diffOneMinusTwo = new ArrayList<>(listOne); // copy
diffOneMinusTwo.removeIf(x -> listTwoStrings.contains(x.getString()));
Use Stream API filter and collect - no copy is needed here but a temporary set of strings is used
List<MyObject> diffOneMinusTwo = listOne
.stream()
.filter(x -> !listTwoStrings.contains(x.getString()))
.collect(Collectors.toList());
In Java 11 there is static Predicate::not method so the stream version may look like this (if hashCode and equals are implemented properly):
List<MyObject> diffOneMinusTwo = listOne
.stream()
.filter(Predicate.not(listTwo::contains)) // using method reference
.collect(Collectors.toList());
The difference between listTwo and listOne can be created vice versa.
I've searched through many questions on this site with somewhat similar underlying concepts, however after many hours of attempting to solve this problem myself and reviewing I am still lost. If there is another question that answers this I will be more than happy to give it a look over.
Ultimately I want to create a recursive method such that it takes two lists and returns a Set of String lists:
//Example of such a function definition
private static Set<List<String>> myRecursiveMethod(List<String> listOne,
List<String> listTwo) {
}
When I say "Set of String lists" I mean specifically the following:
(Note:"AD" == "DA")
// if the two following lists are INPUTTED into myRecursiveMethod();
// listOne = ["A","B"]
// listTwo = ["C","D"]
// the following set is OUTPUTTED: [["AC","BD"],["AD","BC"]]
Such that if there were three elements in both listOne and listTwo, there would be SIX elements in the set. i.e:
// listOne = ["A","B","C"]
// listTwo = ["D","E","F"]
// OUTPUTTED: [["AD","BE","CF"],["AD","BF","CE"],["BD","AE","CF"],
// ["BD","AF","CE"],["CD","AE","BF"],["CD","AF","BE"]]
I tried writing this using a double enhanced FOR loop so I could understand the logic. My FOR loop approach is terrible and only works for the HARD-CODED limit of list.size() == 2.
// Create Lists and append elements
List<String> listOne = new ArrayList<String>();
listOne.add("A");
listOne.add("B");
List<String> listTwo = new ArrayList<String>();
listTwo.add("C");
listTwo.add("D");
// List One = ["A","B"]
// List Two = ["C","D"]
// Create new List
List<List<String>> newList = new ArrayList<List<String>>();
Integer counter = 0;
for (String s : listOne) {
counter++;
for (String p : listTwo) {
// A HARD-CODED bad implementation of this method
if (counter < 3) {
List<String> newListTwo = new ArrayList<String>();
newListTwo.add(s.concat(p));
newList.add(newListTwo);
} else if (!(counter % 2 == 0)) {
newList.get(1).add(s.concat(p));
} else {
newList.get(0).add(s.concat(p));
}
}
}
System.out.println(newList); // = [["AC","BD"],["AD","BC"]]
Also you can note that I defined List<List<String>> Rather than Set<List<String>>. This was due to my badly coded attempted which relies on the list.get() method.
So my current recursive method is as follows:
private static Set<List<String>> myRecursiveMethod(List<String> listOne,
List<String> listTwo)
{
//Base Case:
if (listOne.isEmpty){
return new HashSet<List<String>>;
}
//Recursive Case:
else {
String listOneFirst = listOne.get(0);
String listTwoFirst = listTwo.get(0);
List<String> sampleList = new ArrayList<String>();
sampleList.add(listOneFirst+listTwoFirst);
Set<List<String>> newSet = new HashSet<List<String>>(myRecursiveMethod())
newSet.add(sampleList);
return newSet;
}
}
This method only acts like this currently:
INPUT:
List One = ["A","B"]
List Two = ["C","D"]
OUTPUT:
[["AC"]["BD"]]
DESIRED OUTPUT:
[["AC","BD"],["AD","BC"]]
EDIT:
After reviewing responses my W.I.P code for the class:
private static Set<List<String>> myRecursiveMethod(List<String> listOne,
List<String> listTwo) {
//Backup Case (user enters an empty list)
if (listOne.isEmpty()){
return new HashSet<List<String>>();
}
// Base Case:
if (listOne.size() == 1) {
List<String> mergedStrings = new ArrayList<>();
for (String s : listTwo) {
mergedStrings.add(listOne.get(0).concat(s));
}
Set<List<String>> builtHashSet = new HashSet<List<String>();
builtHashSet.add(mergedStrings);
return builtHashSet;
}
// Recursive Case:
else {
// Ensure original list values arn't changed.
List<String> newListOne = new ArrayList<String>(listOne);
List<String> newListTwo = new ArrayList<String>(listTwo);
//first two elements...I don't think this is correct
String listOneFirst = newListOne.get(0);
String listTwoFirst = newListTwo.get(0);
List<String> sampleList = new ArrayList<String>();
sampleList.add(listOneFirst + listTwoFirst);
//used for making recursive case smaller
newListOne.remove(0);
// Calls recursion
Set<List<String>> newSet = new HashSet<List<String>>(
myRecursiveMethod(newListOne, newListTwo));
newSet.add(sampleList);
return newSet;
}
}
I think the problem is here:
if (listOne.isEmpty){
return new HashSet<List<String>>;
}
You are correct, at some point your recursion has to end, and you have to start building the desired output. But the desired output is not a Set with an empty list. It is a Set containing some lists with some content. Thus: don't wait until listOne is empty. Instead:
if (listOne.size() == 1) {
List<String> mergedStrings = new ArrayList<>();
mergedStrings = ... merge the ONE listOne entry with all listTwo entries
Set<List<String>> rv = new HashSet<>();
rv.add(mergedStrings);
return rv;
}
In other words: you use recursion to reduce the length of the first list by one. And when only one element is left in that list, it is time to merge in the second list.
Now lets look into how to "use" that (calling the method rec for brevity); putting down some pseudo code to show the steps we need:
rec([a, b], [c,d]) -->
rec([a], [c,d]) X rec([b], [c, d]) -->
<[ac, ad]> X <[bc, bd]> -->
<[ac, ad], [bc, bd]>
"X" meaning "joining" two results from recursive calls; should be as easy as:
Set<List<String>> rec1 = rec(...);
return rec1.addAll(rec2 ...
Trying to combine two ArrayList into one, below are the values of two List. W_VISIT describes how many time particular HOST_ADDR address visited the web page.
HOST_ADDR -- W_VISIT
10.202.64.52 -- 11
10.202.64.78 -- 5
10.202.64.34 -- 1
HOST_ADDR -- W_VISIT
10.146.84.179 -- 1
10.202.64.52 -- 16
10.202.64.78 -- 18
All I am trying do here is combine both array list(kind of full outer join in SQL)
Output:
10.202.64.52 -- 11 -- 16
10.202.64.78 -- 5 -- 18
10.202.64.34 -- 1 -- 0
10.146.84.179 -- 0 -- 1
and so on..
public List getData()
{
data=new ArrayList();
ResultSet rs=ps.executeQuery();
while(rs.next()){
fetchValue=new NewClass();
fetchValue.setCount(rs.getInt(1));
fetchValue.setIp(rs.getString(2));
data.add(fetchValue);
}
return data;
}
public List get2Data()
{
data1=new ArrayList();
ResultSet rs=ps.executeQuery();
while(rs.next()){
fetchValue1=new NewClass();
fetchValue1.setCount(rs.getInt(1));
fetchValue1.setIp(rs.getString(2));
data1.add(fetchValue1);
}
return data1;
}
public List get3Data(){
//what to do here... not looking for code, just seeking a way to do
}
Create a new class called IpDetails say with three fields
ip
count 1 --give some good name
count 2
Define a map at Object level with ip as key and IpDetails as value.
When you fire your first query, populate the map by creating IpDetails object and populating things you get from Query and leave count 2 as uninitialized.
When you fire second query do the following:
From the map, get the corresponding IpDetails given ip address as key.
populate count2 field now
And now you have all three details in place, so you can pass on values to the GUI as collections of IpDetails.
Maybe you can output the result like this?
And also you can take an Object result from this.
public void tester() {
final List<NewClass> list1 = new ArrayList<NewClass>();
NewClass fetchValue11 = new NewClass();
fetchValue11.setIp("10.202.64.52");
fetchValue11.setCount(11);
NewClass fetchValue12 = new NewClass();
fetchValue12.setIp("127.0.0.1");
fetchValue12.setCount(5);
NewClass fetchValue13 = new NewClass();
fetchValue13.setIp("0:0:0:0:0:0:1");
fetchValue13.setCount(1);
list1.add(fetchValue11);
list1.add(fetchValue12);
list1.add(fetchValue13);
final List<NewClass> list2 = new ArrayList<NewClass>();
NewClass fetchValue21 = new NewClass();
fetchValue21.setIp("10.202.64.52");
fetchValue21.setCount(16);
NewClass fetchValue22 = new NewClass();
fetchValue22.setIp("127.0.0.1");
fetchValue22.setCount(0);
NewClass fetchValue23 = new NewClass();
fetchValue23.setIp("0:0:0:0:0:0:1");
fetchValue23.setCount(4);
NewClass fetchValue24 = new NewClass();
fetchValue24.setIp("10.202.64.78");
fetchValue24.setCount(18);
list2.add(fetchValue21);
list2.add(fetchValue22);
list2.add(fetchValue23);
list2.add(fetchValue24);
List<NewClass> list = new ArrayList<NewClass>();
list.addAll(list2);
list.addAll(list1);
System.out.println(list.size());
Collections.sort(list, new Comparator<NewClass>() {
public int compare(final NewClass o1, final NewClass o2) {
if (o1.getIp().equals(o2.getIp())) {
System.out.println(o1.getIp() + "---" + o1.getCount() + "---" + o2.getCount());
}
return o1.getIp().compareTo(o2.getIp());
}
});
}
What about this one?
public List get3Data() {
final List<NewClass[]> data3 = new ArrayList<NewClass[]>();
List<NewClass> list = new ArrayList<NewClass>();
list.addAll(data);
list.addAll(data1);
Collections.sort(list, new Comparator<NewClass>() {
public int compare(final NewClass o1, final NewClass o2) {
if (o1.getIp().equals(o2.getIp())) {
data3.add(new NewClass[]{o1, o2});
}
return o1.getIp().compareTo(o2.getIp());
}
});
return data3;
}
I try to implement a hashmap like HashMap<String,MyBigList>
But I can't form my MyBigList. The following is the exact HashMap i'm trying to create.
{word=[ [1, [0, 2] ], [ 2, [2]] ], word2=[ [ 1, [1] ] ]}
I want a big list of single lists like the following
[ [single list], [single list], .. ]
and the single list containing an int and a list of ints
[single list] = [1, [0,2]]
I tried using an ArrayList inside an ArrayList inside an ArrayList, but it didn't work.
I even tried creating a new class having as members an int, and a ArrayList<Integer>
but it didn't work either.
import java.util.ArrayList;
import java.util.HashMap;
public class NewClass {
int id;
ArrayList<Integer> posList;
public NewClass(){
this.id = 0;
this.posList = new ArrayList<Integer>();
}
public NewClass(int _id, int a, int b){
id = _id;
this.posList = new ArrayList<Integer>();
posList.add(a);
posList.add(b);
}
public String toString(){
return "" + this.id + " " + this.posList;
}
public static void main(String[] args) {
NewClass n = new NewClass(1,2,3);
HashMap<String,ArrayList<ArrayList<NewClass>>> map = new HashMap<String,ArrayList<ArrayList<NewClass>>>();
ArrayList<ArrayList<NewClass>> bigList = new ArrayList<ArrayList<NewClass>>();
ArrayList<NewClass> nList = new ArrayList<NewClass>();
nList.add(n);
nList.add(n);
bigList.add(nList);
map.put("word", bigList);
System.out.println(map);
}
}
produces
{word=[[1 [2, 3], 1 [2, 3]]]}
So a Map<String, List<Object>> with no type safety around the sublist (seeing as you have Integers and lists)?
That sounds overcomplicated to put it lightly. They don't have Collections so that you can nest them for all your data, if you really want to make data easy, use a class to represent it, and store that class in a Map using some aspect as a key to get to it:
public class MyClass {
private final String word;
public MyClass(String word) {
this.word = word;
}
// Other Data needed
public String getWord() { return this.word; }
}
//In another class
Map<String, MyClass> words = new HashMap<>();
My problem is can't get an object "Item" (value) from my Treemap. I need send that info to my GUI class and display it in JList to get a select list, so can easily select and add songs to playlist, but only what I get as an output is "01, 02, 03, 04, 05" (key). Please help, because I'm beginner and have no idea what to do.
public class LibraryData {
private static class Item {
Item(String n, String a, int r) {
name = n;
artist = a;
rating = r;
}
// instance variables
private String name;
private String artist;
private int rating;
private int playCount;
public String toString() {
return name + " - " + artist;
}
}
private static Map<String, Item> library = new TreeMap<String, Item>();
static {
library.put("01", new Item("How much is that doggy in the window", "Zee-J", 3));
library.put("02", new Item("Exotic", "Maradonna", 5));
library.put("03", new Item("I'm dreaming of a white Christmas", "Ludwig van Beethoven", 2));
library.put("04", new Item("Pastoral Symphony", "Cayley Minnow", 1));
library.put("05", new Item("Anarchy in the UK", "The Kings Singers", 0));
}
public static String[] getLibrary() {
String [] tempa = (String[]) library.keySet().toArray(new String[library.size()]);
return tempa;
}
SOLUTION:
Because I've to pass the values to another class:
JList tracks = new JList(LibraryData.getLibrary());
I made something like that and it's works
public static Object[] getLibrary() {
Collection c = library.values();
return c.toArray(new Item[0]);
Thank You guys, after 10 hours I finally done it!
}
With this code that you have:
String [] tempa = (String[]) library.keySet().toArray(new String[library.size()]);
You are getting all keys from the map. If you want all values, then use:
library.values();
Finally, if you need to get a value by key use V get(Object key):
library.get("01");
Which will return you the first Item from the map.
It's not very clear which one of these you want, but basically these are the options.
** EDIT **
Since you want all values you can do this:
library.values().toArray()
JList expects an array or vector of Object so this should work.
If you want to get value and key by position, you can use:
key: library.keySet().toArray()[0]
value: library.get(key);
OR (if you just want value)
library.values().toArray()[0];
You can use the ArrayList:
1 - The best for flexible-array managing in Java is using ArrayLists
2 - ArrayLists are easy to add, get, remove and more from and to.
3 - Treemaps are a little... arbitrary. What I say is that if you use the get(Object o) method from a Treemap, the Object o must be a key, which is something not very flexible.
If you want them, use this code:
import java.util.ArrayList;
import com.example.Something; // It can be ANYTHING
//...
ArrayList<Something> somethingList = new ArrayList<Something>();
//...
somethingList.add(new Something("string", 1, 2.5, true));
//...
boolean isSomething = somethingList.get(somethingList.size() - 1); // Gets last item added
//...
int listSize = somethingList.size();
//...
somethingList.remove(somethingList.size() - 1); // Removes last item and decrements size
//...
Something[] nativeArray = somethingList.toArray(new Something[somethingList.size()]); // The parameter is needed or everthing will point to null
// Other things...
Or the classic Treemap:
Object keyAtIndex0 = library.keySet.toArray(new Object[library.size()])[0];
Object value = library.get(keyAtIndex0);
Good Luck!
I was returning a list of string values as treemap value. The used approach is
private Map<String, TreeSet<String>> result;
TreeSet<String> names= result.get(key);
for(String contactName: names){
print contactName;
}