I would like to split an ArrayList that I am looping trough and set a field called active which can be true or false. But at the end of loop I would like to split this collection in two groups.. active = false and active = true, so doing this I won't need to search in database twice..
for example:
private List<Classes> searchClasses(ClassItems listItems) {
List<ClassItem> items = new ArrayList<ClassItem>();
for (Iterator<ClassItem> iterator = listItems.getItems().iterator(); iterator.hasNext();) {
ClassItems item = iterator.next();
ClassEntityManager classEnt = ClassEntityManager.search(item.getId);
if(classEnt.active()){
item.setActive(true);
items.add(item);
}
}
return items;
}
What is the best approach to do this??
Make two lists instead of one.
if(classEnt.active()) {
activeItems.add(item);
item.setActive(true);
} else {
inactiveItems.add(item);
}
Use two collections, one for actives and the other for not actives.
When you fetch the data from the DB, simply put the CalssItem in the correct list:
private List<ClassItem> searchClasses(ClassItems listItems) {
List<ClassItem> activeItems= new ArrayList<ClassItem>();
List<ClassItem> notActiveItems= new ArrayList<ClassItem>();
Iterator<ClassItem> i = listItems.getItems().iterator();
while(i.hasNext()) { //This is a better approach.
ClassEntityManager classEnt = ClassEntityManager.search(i.next().getId);
if(classEnt.active()){
item.setActive(true);
activeItems.add(item);
}else{
item.setActive(false);
notActiveItems.add(item);
}
}
List<ClassItem> ret = new ArrayList<ClassItem>(activeItems);
ret.addAll(notActiveItems);
return ret;
}
BUT, in this way, both activeItems and notActiveItems are unreacheable. Best thing to do is to have a loop outside your method that checks if the ClassItem is active or not. In this way both activeItems and notActiveItems can be deleted from the method:
private List<ClassItem> searchClasses(ClassItems listItems) {
List<ClassItem> items= new ArrayList<ClassItem>();
Iterator<ClassItem> i = listItems.getItems().iterator();
while(i.hasNext()) { //This is a better approach.
ClassEntityManager classEnt = ClassEntityManager.search(i.next().getId);
item.setActive(classEnt.active());
items.add(item);
}
return items;
}
And to use the list:
List<ClassItem> items = searchClasses(classItems);
for(ClassItem item: items){
if(item.isActive()){
//do something
}else{
//do something else
}
}
Better yet is to use the magnificient and beautiful Java 8 Stream API:
List<ClassItem> active = items.stream().filter(x->x.isActive).collect(Collectors.toList());
List<ClassItem> notActive = items.stream().filter(x->!x.isActive).collect(Collectors.toList());
or the one liner:
List<ClassItem> active = searchClasses(classItems).stream().filter(x->x.isActive).collect(Collectors.toList());
NOTES:
Your code has a return type of List<Classes>, while the returned value is of List<ClassItem>. Which is right?
Your iterator has a generic type of ClassItem while the next() method returns a ClassItems object. Which is right?
I've wrote a method in my implementation of my interface that takes a linked list in parameter and has to return an arraylist of all the items that exists already and weren't added to the class list.
Here's the signature:
public List<T> addBegining(ListeOfEmployees<T> list);
My methode add's the elements in the linked list of the class in inverse.
Lets say the parameter list:
Employee1
Employee2
Employee3
Employee4
Employee5
Actual list in the class:
Employee2
Employee4
Employee5
It's suppose to return an ArrayList in the same order of the parameter list:
1-Employee2
2-Employee4
3-Employee5
But it returns an ArrayList like this:
1-Employee5
2-Employee4
3-Employee2
I used a while() to cycle thru my parametered list but it goes from begining to end.
I don't know how I can cycle thrue the parameterized list but from the end to the beginning.
I cannot use a pointer at the end of the list for this method.
I'm out of solutions here.
Here's what i've done so far:
public List<T> addBegining(ListeOfEmployees<T> list) {
List<T> res = null;
T return;
Iterator<T> it = list.iterator();
while (it.hasNext() && list != null) {
return = it.next();
if (this.hasElement(return)) {
if (res == null) {
res = new ArrayList<T>();
}
res.add(retour);
} else {
this.addBegining(retour);
nbElm++;
}
}
return res;
}
private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {
String newCD = (cdInput.getText());
List <String> cdList = new ArrayList();
Collections.addAll(cdList, "ExampleG","ExampleB","ExampleR","ExampleX");
cdList.add(""+newCD);
List<String> sorted = new ArrayList<String>(cdList);
Collections.sort(sorted);
bigBox.setText("");
bigBox.append("Original Order\n**************\n");
for (String o : cdList) {
bigBox.append(o);
bigBox.append("\n");
}
bigBox.append("\n\nSorted Order\n************\n");
for (String s : sorted) {
bigBox.append(s);
bigBox.append("\n");
}
}
With this code, I can add 1 value, but when I try to add another one, it erases the original and replaces it. What can I do to prevent this?
PS. I'm trying to make a List of CDs, and be able to add new ones and have them also sorted and put in thier original order
Based on your code, you have no centralised instance of List, which means, each time you activate the button, it has no concept of what was previously in the list.
Start by creating an instance variable of the cd List and only add new items to it as required.
Something more like...
private List<String> cdList = new ArrayList<>(25);
private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {
String newCD = (cdInput.getText());
cdList.add(newCD);
List<String> sorted = new ArrayList<String>(cdList);
Collections.sort(sorted);
bigBox.append("Original Order\n**************\n");
for (String o : cdList) {
bigBox.append(o);
bigBox.append("\n");
}
bigBox.append("\n\nSorted Order\n************\n");
for (String s : sorted) {
bigBox.append(s);
bigBox.append("\n");
}
}
I have an array list which when populated has a key and a value I want to know if there is a way of splitting it on repeating keys for example my current data is like this:
[RoleID_123.0, UserHandel_tom, Password_12345.0, prevPassword_null, userCaption_thomas, Email_tom#tom.tom, RoleID_124.0, UserHandel_dave, Password_ghadf, prevPassword_sdfsd, userCaption_david, Email_dave#dave.dave, RoleID_125.0, UserHandel_trevor, Password_tre, prevPassword_null, userCaption_trev, Email_trev#trev.trev]
I want it to come out more like this:
[RoleID_123.0, UserHandel_tom, Password_12345.0, prevPassword_null, userCaption_thomas, Email_tom#tom.tom]
[RoleID_124.0, UserHandel_dave, Password_ghadf, prevPassword_sdfsd, userCaption_david, Email_dave#dave.dave]
[RoleID_125.0, UserHandel_trevor, Password_tre, prevPassword_null, userCaption_trev, Email_trev#trev.trev]
Is there a way to split it on say role id or am I going about this the wrong way?
You can try by using HashMap
private static class MyItemHashMap extends HashMap {
public Item add(Item item) {
get(item).add(item);
return item;
}
public List get(Item key) {
List list = (List) get(createItemKey((Item) key));
return list == null ? createItemEntry((Item) key) : list;
}
private List createItemEntry(Item item) {
List list = new ArrayList();
put(createItemKey(item), list);
return list;
}
private Object createItemKey(Item item) {
return item.getSplitterProperty();
}
}
public static void main(String[] args) {
MyItemHashMap itemMapped = new MyItemHashMap();
List items = Arrays.asList(new Object[]{new Item("A"), new Item("B"),
new Item("C")});
for (Iterator iter = items.iterator(); iter.hasNext();) {
Item item = (Item) iter.next();
itemMapped.add(item);
}
}
If it is an ArrayList, there is no built-in function to split data like this; you will have to do it manually. If you know the number of consecutive fields that make a single structure, this shouldn't be too hard; something like this:
// 6 because there are 6 fields
for (int i = 0; i < arrayList.size(); i = i + 6) {
List thisList = arrayList.subList(i, i + 5);
// ... Now do whatever you want with thisList - it contains one structure.
}
If the number of fields can change then you'll have to do something a little more dynamic and loop through looking for a RoleID field, for example.
I'd use a HashMap to seperate the data instead of one long ArrayList ( you shouldn't have stored the data like this in the first instance )
HashMap<String,ArrayList<String>> hm = new HashMap<String,ArrayList<String>>;
// For each list:
ArrayList<String> arr = new ArrayList<String>;
arr.add("each element");
hm.put("RoleID_123.0", arr);
This way you will end up with a three dimensional structure with a key ( "RoleID..." ) pointing to its child elements.
Try this
String[] str=new String[]{"RoleID_123.0", "UserHandel_tom", "Password_12345.0", "prevPassword_null", "userCaption_thomas", "Email_tom#tom.tom", "RoleID_124.0", "UserHandel_dave", "Password_ghadf", "prevPassword_sdfsd", "userCaption_david", "Email_dave#dave.dave", "RoleID_125.0", "UserHandel_trevor", "Password_tre", "prevPassword_null", "userCaption_trev", "Email_trev#trev.trev"};
List<String> list=new ArrayList<>(Arrays.asList(str));
List<String> subList=list.subList(0,5);
You can try something similar to this
If you feel like taking a Linq-ee Libraried approach, this is about as good as it gets, and it requires use of a couple delegate objects:
import static com.google.common.collect.Collections2.filter;
import static com.google.common.collect.Collections2.transform;
//...
final List<String> yourList = //...
final int RECORD_LENGTH = 6;
Collection<String> roleIdValues = filter(yourList, new Predicate<String>() {
public boolean apply(#Nullable String input) {
return input != null && input.startsWith("RoleID");
}
});
Collection<Collection<String>> splitRecords = transform(roleIdValues, new Function<String, Collection<String>>() {
#Nullable public Collection<String> apply(#Nullable String input) {
return yourList.subList(yourList.indexOf(input), RECORD_LENGTH);
}
});
If Oracle had delivered Java 8 on time you would be able to do this in a way more slick manor. Ironically the reason you cant was provided by the same people providing the guava library
I have created a collection and filled it with elements which are collections too, but when I tried to iterate through this container using a foreach construction (or other methods) it returns me nothing, I tried to get size() and saw what I expect (appropriate number) but seems like nevertheless container not empty inside each collection is null
Code snippet example:
Item it1, it2;
List<Collection<Item>> hull = new ArrayList<Collection<Item>>();
List<Item> seq = new ArrayList<Item>();
seq.add(it1);
hull.add(seq);
seq.clear();
seq.add(it2);
hull.add(seq);
for (<Collection<Item> c: hull)
System.out.println(c);
This is just an simplified snippet of what I do
Please suggest alternatives. Where did I make a mistake?
Each time you call seq.clear() you empty the inner ArrayList. Don't forget that when you add an object to a Collection, you only add the reference. You don't clone the Object. You should create a new ArrayList Object at each iteration.
E.g.
List<Collection<Item>> hull = new ArrayList<Collection<Item>>();
List<Item> seq = new ArrayList<Item>();
seq.add(it1);
hull.add(seq);
List<Item> seq2 = new ArrayList<Item>();
seq2.add(it2)
hull.add(seq2);
EDIT:
Complete Sample that compiles:
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class NewClass1 {
static class Item {
String a;
public Item(String a) {
this.a = a;
}
#Override
public String toString() {
return a;
}
}
public static void main(String[] args) {
List<Collection<Item>> hull = new ArrayList<Collection<Item>>();
List<Item> seq = new ArrayList<Item>();
Item it1 = new Item("item 1");
seq.add(it1);
hull.add(seq);
List<Item> seq2 = new ArrayList<Item>();
Item it2 = new Item("item 2");
seq2.add(it2);
hull.add(seq2);
for (Collection<Item> current : hull) {
for (Item item : current) {
System.out.println(item);
}
}
}
}
Output:
run:
item 1
item 2
Your code, corrected to compile:
package sample;
import java.util.ArrayList;
import java.util.List;
public class Item {
public static void main( String[] args ) {
List< List< Item >> hull = new ArrayList<>();
List< Item > seq = new ArrayList<>();
seq.add( new Item());
hull.add( seq );
seq = new ArrayList<>(); // in place of seq.clear();
seq.add( new Item());
hull.add( seq );
for( List<Item> c: hull ) {
System.out.println( c.get( 0 ));
}
}
}
ouputs:
sample.Item#6da264f1
sample.Item#40914272
As you can see, there is no problem.
In order to iterate through a collection of collections you need a nested foreach.
for(Collection<Item> c: hull)
{
for(Item i: c)
{
}
}
By the way, are you aware that it1 and it2 are not initialized and that's why you are getting nothing?
size() will always give you the size of the collections, but they might be containing nulls (as it is your case).