ConcurrentModificationException thrown by crop(x) and a.setFrom() - java

I am current lost in that problem. I have read a lot here about other problems with ConcurrentModificationException, but can't resolve my problem. Maybe i don't see the wood for the trees. I hope you can help me. The method is
public void crop(PesNode n) {
for (int ii = n.getPostNodes().size()-1; ii >= 0; ii--) {
for (int i = ii-1; i >= 0; i--) {
PesNode n1=n.getPostNodes().get(i);
PesNode n2=n.getPostNodes().get(ii);
if (n1.getName().equals(n2.getName())) {
boolean merge=true;
for (PesNode node : n1.getPreNodes()) {
if (!n2.getPreNodes().contains(node)) {
merge=false;
}
}
for (PesNode node : n2.getPreNodes()) {
if (!n1.getPreNodes().contains(node)) {
merge=false;
}
}
if (merge) {
//Merge n1 and n2
//for(Iterator<PesArc> itPesArc = n2.getPost().iterator(); itPesArc.hasNext();) { PesArc a = itPesArc.next();
for(PesArc a : n2.getPost()) {
a.setFrom(n1);
n1.getPost().add(a);
}
//for(Iterator<PesArc> itPesArc = n2.getPost().iterator(); itPesArc.hasNext();) { PesArc a = itPesArc.next();
for(PesArc a : n2.getPre()) {
arcs.remove(a);
a.getFrom().getPost().remove(a);
}
//for(Iterator<Integer> it = n2.getCoset().iterator(); it.hasNext();) { int j = it.next();
for (int j : n2.getCoset()) {
if (!n1.getCoset().contains(j)) {
n1.getCoset().add(j);
}
}
nodes.remove(n2);
//n2.getPost().removeIf(Objects::isNull);
//n2.getPre().removeIf(Objects::isNull);
//n2.getCoset().removeIf(Objects::isNull);
i=0;
}
}
}
}
for (PesNode x : n.getPostNodes()) {
crop(x);
}
The errors comes from the "crop(x)" at the end and pops up at "a.setFrom(n1);"
I dont understand why this happens, because every for loop comes to its ends before the next one starts. I also tried to use iterators instead of the for loops, without any solution. What do I wrong?

You get ConcurrentModificationException because you try to remove element while you are using for operator. So I think the line in your code nodes.remove(n2); can lead to this exception. You can use Iterator or just to gather the elements for removal in another Collection and then remove it. For more information: https://www.baeldung.com/java-concurrentmodificationexception

Related

How to generate inner loops automatically in Java

I am trying to find a way to generate inner loops on demand (and have the depth as a variable).
In the following example, I am trying to generate a list of references such as jobo.2.2.2.2.2.2 where each .2 is added in the inner loop.
Here is what I have at the moment when I implement the new loop manually for 5 level of depth (i, j, k, l):
public void buildTaskList(){
String jobName ="jobo";
String last="";
long max=3;
List<String> tasks = new ArrayList<>();
for (long i = 1; i <= max; i++) {
for (long j = 1; j <= max; j++) {
if (j==max){
last="*";
tasks.add(jobName+"."+i+"."+j+last);
}else {
last="";
for (long k = 1; k <= max; k++) {
if (k==max){
last="*";
tasks.add(jobName+"."+i+"."+j+"."+k+last);
}else {
last="";
for (long l = 1; l <= max; l++) {
if (l==max){
last="*";
tasks.add(jobName+"."+i+"."+j+"."+k+"."+l+last);
}else{
last="";
for (long m = 1; m <= max; m++) {
if (m==max){
last="*";
tasks.add(jobName+"."+i+"."+j+"."+k+"."+l+"."+m+last);
}else{
last="";
for (long n = 1; n <= max; n++) {
if (n==max)last="*";else last="";
tasks.add(jobName+"."+i+"."+j+"."+k+"."+l+"."+m+"."+n+last);
}
}
}
}
}
}
}
}
}
}
tasks.add(jobName+"."+(max+1)+last);
System.out.println(tasks);
}
The result here is:
jobo.1.1.1.1.1.1, jobo.1.1.1.1.1.2, jobo.1.1.1.1.1.3*, jobo.1.1.1.1.2.1, jobo.1.1.1.1.2.2, jobo.1.1.1.1.2.3*, jobo.1.1.1.1.3*, jobo.1.1.1.2.1.1, jobo.1.1.1.2.1.2, jobo.1.1.1.2.1.3*, jobo.1.1.1.2.2.1, jobo.1.1.1.2.2.2, jobo.1.1.1.2.2.3*, jobo.1.1.1.2.3*, jobo.1.1.1.3*, jobo.1.1.2.1.1.1, jobo.1.1.2.1.1.2, jobo.1.1.2.1.1.3*, jobo.1.1.2.1.2.1, jobo.1.1.2.1.2.2, jobo.1.1.2.1.2.3*, jobo.1.1.2.1.3*, jobo.1.1.2.2.1.1, jobo.1.1.2.2.1.2, jobo.1.1.2.2.1.3*, jobo.1.1.2.2.2.1, jobo.1.1.2.2.2.2, jobo.1.1.2.2.2.3*, jobo.1.1.2.2.3*, jobo.1.1.2.3*, jobo.1.1.3*, jobo.1.2.1.1.1.1, jobo.1.2.1.1.1.2, jobo.1.2.1.1.1.3*, jobo.1.2.1.1.2.1, jobo.1.2.1.1.2.2, jobo.1.2.1.1.2.3*, jobo.1.2.1.1.3*, jobo.1.2.1.2.1.1, jobo.1.2.1.2.1.2, jobo.1.2.1.2.1.3*, jobo.1.2.1.2.2.1, jobo.1.2.1.2.2.2, jobo.1.2.1.2.2.3*, jobo.1.2.1.2.3*, jobo.1.2.1.3*, jobo.1.2.2.1.1.1, jobo.1.2.2.1.1.2, jobo.1.2.2.1.1.3*, jobo.1.2.2.1.2.1, jobo.1.2.2.1.2.2, jobo.1.2.2.1.2.3*, jobo.1.2.2.1.3*, jobo.1.2.2.2.1.1, jobo.1.2.2.2.1.2, jobo.1.2.2.2.1.3*, jobo.1.2.2.2.2.1, jobo.1.2.2.2.2.2, jobo.1.2.2.2.2.3*, jobo.1.2.2.2.3*, jobo.1.2.2.3*, jobo.1.2.3*, jobo.1.3*, jobo.2.1.1.1.1.1, jobo.2.1.1.1.1.2, jobo.2.1.1.1.1.3*, jobo.2.1.1.1.2.1, jobo.2.1.1.1.2.2, jobo.2.1.1.1.2.3*, jobo.2.1.1.1.3*, jobo.2.1.1.2.1.1, jobo.2.1.1.2.1.2, jobo.2.1.1.2.1.3*, jobo.2.1.1.2.2.1, jobo.2.1.1.2.2.2, jobo.2.1.1.2.2.3*, jobo.2.1.1.2.3*, jobo.2.1.1.3*, jobo.2.1.2.1.1.1, jobo.2.1.2.1.1.2, jobo.2.1.2.1.1.3*, jobo.2.1.2.1.2.1, jobo.2.1.2.1.2.2, jobo.2.1.2.1.2.3*, jobo.2.1.2.1.3*, jobo.2.1.2.2.1.1, jobo.2.1.2.2.1.2, jobo.2.1.2.2.1.3*, jobo.2.1.2.2.2.1, jobo.2.1.2.2.2.2, jobo.2.1.2.2.2.3*, jobo.2.1.2.2.3*, jobo.2.1.2.3*, jobo.2.1.3*, jobo.2.2.1.1.1.1, jobo.2.2.1.1.1.2, jobo.2.2.1.1.1.3*, jobo.2.2.1.1.2.1, jobo.2.2.1.1.2.2, jobo.2.2.1.1.2.3*, jobo.2.2.1.1.3*, jobo.2.2.1.2.1.1, jobo.2.2.1.2.1.2, jobo.2.2.1.2.1.3*, jobo.2.2.1.2.2.1, jobo.2.2.1.2.2.2, jobo.2.2.1.2.2.3*, jobo.2.2.1.2.3*, jobo.2.2.1.3*, jobo.2.2.2.1.1.1, jobo.2.2.2.1.1.2, jobo.2.2.2.1.1.3*, jobo.2.2.2.1.2.1, jobo.2.2.2.1.2.2, jobo.2.2.2.1.2.3*, jobo.2.2.2.1.3*, jobo.2.2.2.2.1.1, jobo.2.2.2.2.1.2, jobo.2.2.2.2.1.3*, jobo.2.2.2.2.2.1, jobo.2.2.2.2.2.2, jobo.2.2.2.2.2.3*, jobo.2.2.2.2.3*, jobo.2.2.2.3*, jobo.2.2.3*, jobo.2.3*, jobo.3.1.1.1.1.1, jobo.3.1.1.1.1.2, jobo.3.1.1.1.1.3*, jobo.3.1.1.1.2.1, jobo.3.1.1.1.2.2, jobo.3.1.1.1.2.3*, jobo.3.1.1.1.3*, jobo.3.1.1.2.1.1, jobo.3.1.1.2.1.2, jobo.3.1.1.2.1.3*, jobo.3.1.1.2.2.1, jobo.3.1.1.2.2.2, jobo.3.1.1.2.2.3*, jobo.3.1.1.2.3*, jobo.3.1.1.3*, jobo.3.1.2.1.1.1, jobo.3.1.2.1.1.2, jobo.3.1.2.1.1.3*, jobo.3.1.2.1.2.1, jobo.3.1.2.1.2.2, jobo.3.1.2.1.2.3*, jobo.3.1.2.1.3*, jobo.3.1.2.2.1.1, jobo.3.1.2.2.1.2, jobo.3.1.2.2.1.3*, jobo.3.1.2.2.2.1, jobo.3.1.2.2.2.2, jobo.3.1.2.2.2.3*, jobo.3.1.2.2.3*, jobo.3.1.2.3*, jobo.3.1.3*, jobo.3.2.1.1.1.1, jobo.3.2.1.1.1.2, jobo.3.2.1.1.1.3*, jobo.3.2.1.1.2.1, jobo.3.2.1.1.2.2, jobo.3.2.1.1.2.3*, jobo.3.2.1.1.3*, jobo.3.2.1.2.1.1, jobo.3.2.1.2.1.2, jobo.3.2.1.2.1.3*, jobo.3.2.1.2.2.1, jobo.3.2.1.2.2.2, jobo.3.2.1.2.2.3*, jobo.3.2.1.2.3*, jobo.3.2.1.3*, jobo.3.2.2.1.1.1, jobo.3.2.2.1.1.2, jobo.3.2.2.1.1.3*, jobo.3.2.2.1.2.1, jobo.3.2.2.1.2.2, jobo.3.2.2.1.2.3*, jobo.3.2.2.1.3*, jobo.3.2.2.2.1.1, jobo.3.2.2.2.1.2, jobo.3.2.2.2.1.3*, jobo.3.2.2.2.2.1, jobo.3.2.2.2.2.2, jobo.3.2.2.2.2.3*, jobo.3.2.2.2.3*, jobo.3.2.2.3*, jobo.3.2.3*, jobo.3.3*, jobo.4*
Anyone knows how this can be simplified and controlled by a variable int depth=123; for example?
Thanks
This option avoids recursion, and simply counts as you would when deciding the next element in the sequence:
private static class LevelGenerator implements Iterator<String> {
private int[] current; // min,min,min => min,min,min+1 => ... max,max,max
private int min, max; // at each position in current[] array
private String next; // to be returned when next() is called
public LevelGenerator(int levels, int min, int max) {
this.current = new int[levels];
for (int i=0; i<levels; i++) this.current[i] = min;
this.next = output();
this.min = min;
this.max = max;
}
/**
* Int array to string
*/
private String output() {
StringBuilder sb = new StringBuilder();
for (int i : current) sb.append("." + i);
return sb.toString();
}
/**
* Updates current and next
* counts as a human would: increments the last index that is not yet `max`,
* and then places all elements after it to `min`
*/
private String step() {
for (int i=current.length-1; i>=0; i--) {
if (current[i] < max) {
current[i] ++;
for (int j=i+1; j<current.length; j++) {
current[j] = min;
}
return output(); // next step is ready
}
}
return null; // no next step
}
#Override
public String next() {
if (next == null) throw new IllegalStateException("iteration is finished");
String output = next;
next = step();
return output;
}
#Override
public boolean hasNext() {
return next != null;
}
}
public static void main(String ... args) {
LevelGenerator l = new LevelGenerator(3, 1, 4);
while (l.hasNext()) {
System.out.println("job" + l.next());
}
}
The output for this example would be:
job.1.1.1
job.1.1.2
job.1.1.3
job.1.1.4
job.1.2.1
job.1.2.2
job.1.2.3
job.1.2.4
job.1.3.1
job.1.3.2
job.1.3.3
job.1.3.4
job.1.4.1
job.1.4.2
job.1.4.3
job.1.4.4
job.2.1.1
...
job.4.4.4
You can use Recursion (see wiki https://en.wikipedia.org/wiki/Recursion_(computer_science))
for example (draft, not checking)
#Test
public void buildTaskList1() {
String jobName ="job";
int depth=5;
int max=3;
List<String> tasks = new ArrayList<>();
for (long i = 1; i <= max; i++) {
buildTaskListRecursion(max, depth, tasks, jobName + "."+i);
}
tasks.add(jobName+"."+(max+1)+"*");
}
public void buildTaskListRecursion(int max,int depth, List<String> tasks, String jobName){
String last="";
for (long j = 1; j <= max; j++) {
if (j==max){
last="*";
tasks.add(jobName+"."+j+last);
}else {
depth--;
if(depth > 0) {
buildTaskListRecursion(max, depth, tasks, jobName+"."+j);
} else {
tasks.add(jobName+"."+j);
}
}
}
}
Yes
1. Support indexes
Create a stack of indexes of the size of depth.
2. Handle the levels properly
You need a currentDepth index to know where you were. This is 0 at first. Whenever an item is increased, push a new item to the stack with 0 as index. Whenever an item is going beyond max, pop it from the stack and increment the previous element. When the first element is popped, you completed all the work
3. You will need to logically know where you were.
Alternatively you could generate code
But that's much more complicated.
EDIT
In agreement with Bdzzaid's legitimate request, I will briefly talk about the Composite Design Pattern. First, let's see a diagram from the page he shared with us:
Source: https://dzone.com/articles/composite-design-pattern-in-java-1
That's a good read I can wholeheartedly recommend to future readers. The idea is that we use the composition of very similar components in a tree-like manner. The pattern is applied on a stack in our case, which can be thought about as a tree having a single branch in all cases. The reason this is beneficial to think about in this way is that we might want to add support for multiple loops, maybe even in an assymmetryc manner at some point. Now, the components are the levels/indexes in our case and they, together form a composition of the stack (or, in more general terms, the tree).
This pattern can be reused in many different situations, so it is advisable to get familiar with it if you not already have.

Observe livedata inside a for loop

I want to update a list in my activity that depends on the data of another list. Both the data list are being observed from the activity from the my viewmodel. After I get the data from my firstlist I need to run a for loop on this list to get the required ids and get the data for the second list.
But keeping the livedata observer in the for loop is causing a lot of problems. The for loop runs as expected but the livedata observer is getting called almost double the amount of the for loop. This happens only the first time when the list in being brought from the api. When I do the same operation a second time where the list is cached and is being brought from the database, the problem does not occur. Below is the source code for the problem,
for (int i = 0; i < firstList.size(); i++) {
final String uId = firstList.get(i).item.uid;
final long id = firstList.get(i).item.id;
viewModel.initAnotherItemRepository(uId, id);
viewModel.getSecondItem().observe(this, new Observer<Resource<List<SecondItem>>>() {
#Override
public void onChanged(Resource<List<SecondItem>> listResource) {
if (listResource.data != null) {
secondItemList.addAll(listResource.data);
if (count == firstList.size() - 1) {
//Do something
}
count = count + 1;
}
if (listResource.state == Resource.STATE_FAILURE) {
showLoadingSpinner(false);
}
}
}
);
}
Try to observe SecondItem outside the for loop. It gets data whenever update
viewModel.getSecondItem().observe(this, new Observer<Resource<List<SecondItem>>>() {
#Override
public void onChanged(Resource<List<SecondItem>> listResource) {
if (listResource.data != null) {
secondItemList.addAll(listResource.data);
if (count == firstList.size() - 1) {
//Do something
}
count = count + 1;
}
if (listResource.state == Resource.STATE_FAILURE) {
showLoadingSpinner(false);
}
}
}
);
for (int i = 0; i < firstList.size(); i++) {
final String uId = firstList.get(i).item.uid;
final long id = firstList.get(i).item.id;
viewModel.initAnotherItemRepository(uId, id);
}

How to iterate through a bunch of streams and read one element at a time?

I have a stream class which consists of sorted in ascending order.
class Stream {
boolean hasNext();
int peek();
int next();
}
I need to write a program to merge multiple streams and print out the elements that exist more than a number of times in different streams without repeating.
This is how I design it with pseudo code:
// print out numbers with occurance greater than (k).
void mergeStreams(List<Stream> streams, int k) {
int minCount = 0;
int min = Integer.MAX_VALUE;
List<Stream> minStreams;
loop through each stream and read in elements on head {
if (streams.size() < k) return;
if (!stream.hasNext()) {
streams.remove(stream); continue;
}
if (stream.peek() <= min) {
if (stream.peek() == min) {
minCount++;
}
else {
minStreams = new ArrayList<Stream>();
min = stream.peek();
minCount = 1;
}
minStreams.add(stream);
}
if last stream in streams {
if (minCount >= k) {
System.out.println(min);
for (Stream s : minStreams) {
if (s.hasNext()) s.next();
else streams.remove(s);
}
}
}
Problem is I don't know how exactly to iterate through streams and read on element at a time and hence the pseudo code part. Plus, I am not sure if streams.remove(s) at the bottom of the code really deletes stream s from original list of Streams since it has been added to new list minStreams. I can really use some advice here.
To remove elements from a list while iterating over it, you should use Iterator.remove(). You'll also need a while loop around the whole thing to check more than one value.
void mergeStreams(List<Stream> streams, int k) {
while (streams.size() >= k) { // each loop checks one value (the current minimum)
int minCount = 0;
int min = Integer.MAX_VALUE;
List<Stream> minStreams = new ArrayList<>();
Iterator<Stream> streamIter = streams.iterator(); // supports remove during iteration
while (streamIter.hasNext()) {
Stream stream = streamIter.next();
if (!stream.hasNext()) {
streamIter.remove(); // remove stream from original list
continue;
}
if (stream.peek() <= min) {
if (stream.peek() == min) {
minCount++;
} else {
minStreams = new ArrayList<>();
min = stream.peek();
minCount = 1;
}
minStreams.add(stream);
}
}
if (minCount >= k) { // runs after iterating over streams
System.out.println(min);
}
for (Stream s : minStreams) { // must advance past the current min value
if (s.hasNext()) {
s.next();
} else {
streams.remove(s);
}
}
}
}
I also fixed a bug where the streams in minStreams didn't advance past the minimum value when minCount < k, so it would get stuck on that value.

String index out of range in Java

I am aware there are multiple threads like my assignment below, but I just can't figure it out. I can't exactly figure out the mistake. Help would be appreciated.
I am trying to do this program:
Everything works fine unless I input the same chains or similar (for example ACTG and ACTG or ACTG and ACTGCCCC), when it tells me
string index out of range
This is that part of my code:
int tries=0;
int pos=-1;
int k;
for (int i=0; i<longDNA.length(); i++) {
tries=0;
k=i;
for (int j=0; j<shortDNA.length(); j++) {
char s=shortDNA.charAt(j);
char l=longDNA.charAt(k);
if (canConnect(s,l)) {
tries+=1;
k+=1;
}
}
if (tries==shortDNA.length()-1) {
pos=i-1;
break;
}
}
Let's call the two DNA strings longer and shorter. In order for shorter to attach somewhere on longer, a sequence of bases complementary to shorter must be found somewhere in longer, e.g. if there is ACGT in shorter, then you need to find TGCA somewhere in longer.
So, if you take shorter and flip all of its bases to their complements:
char[] cs = shorter.toCharArray();
for (int i = 0; i < cs.length; ++i) {
// getComplement changes A->T, C->G, G->C, T->A,
// and throws an exception in all other cases
cs[i] = getComplement(cs[i]);
}
String shorterComplement = new String(cs);
For the examples given in your question, the complement of TTGCC is AACGG, and the complement of TGC is ACG.
Then all you have to do is to find shorterComplement within longer. You can do this trivially using indexOf:
return longer.indexOf(shorterComplement);
Of course, if the point of the exercise is to learn how to do string matching, you can look at well-known algorithms for doing the equivalent of indexOf. For instance, Wikipedia has a category for String matching algorithms.
I tried to replicate your full code as fast as I could, I'm not sure if I fixed the problem but you don't get any errors.
Please try it and see if it works.
I hope you get this in time and good luck!
import java.util.Arrays;
public class DNA {
public static void main(String[] args) {
System.out.println(findFirstMatchingPosition("ACTG", "ACTG"));
}
public static int findFirstMatchingPosition(String shortDNA, String longDNA) {
int positionInLong = 0;
int positionInShort;
while (positionInLong < longDNA.length()) {
positionInShort = 0;
while(positionInShort < shortDNA.length()) {
String s = shortDNA.substring(positionInShort, positionInShort + 1);
if(positionInShort + positionInLong + 1 > longDNA.length()) {
break;
}
String l = longDNA.substring(positionInShort + positionInLong, positionInShort + positionInLong + 1);
if(canConnect(s, l)) {
positionInShort++;
if(positionInShort == shortDNA.length()) {
return positionInLong;
}
} else {
break;
}
}
positionInLong++;
if(positionInLong == longDNA.length()) {
return -1;
}
}
return -1;
}
private static String[] connections = {
"AT",
"TA",
"GC",
"CG"
};
private static boolean canConnect(String s, String l) {
if(Arrays.asList(connections).contains((s+l).toUpperCase())) {
return true;
} else {
return false;
}
}
}
I finally changed something with the k as Faraz had mentioned above to make sure the charAt does not get used when k overrides the length of the string and the program worked marvelously!
The code was changed to the following:
int tries=0;
int pos=-1;
int k;
for (int i=0; i<longDNA.length(); i++) {
tries=0;
k=i;
for (int j=0; j<shortDNA.length(); j++) {
if (k<longDNA.length()) {
char s=shortDNA.charAt(j);
char l=longDNA.charAt(k);
if ((s=='A' && l=='T') || (s=='T' && l=='A') || (s=='G' && l=='C') || (s=='C' && l=='G')) {
tries+=1;
k+=1;
}
}
}
if (tries==shortDNA.length()) {
pos=i;
break;
}
}
I am not sure how aesthetically pleasing or correct this excerpt is but - it completely solved my problem, and just 2 minutes before the deadline! :)
A huge thanks to all of you for spending some time to help me!!

How can I refactor this code and apply OO patterns?

I have four RichTable instances in my class and there is a notion of current table instance . Depending on a flag resetAll I need to clear out selections of either all the tables or all tables except the current one . If resetAll is true then clear out everything , otherwise leave out the current one . The index of the current table is passed as a parameter to the method that does the clean up action.
The call for clearing out everything looks like this :
clearSubTypeSettings(true,-1);
The call for clearing all but the current one looks like this :
clearSubTypeSettings(true, col);
The implementation of the above method is this :
private void clearSubTypeSettings(boolean resetAll, int exceptControl) {
if (!resetAll) {
clearAllExceptCurrent(exceptControl);
} else {
clearAll();
}
}
Now these two methods clearAllExceptCurrent(exceptControl) and clearAll() look almost the same . Here are the implementations :
private void clearAll() {
for (int i = 0; i < SUBTYPE_TABLES; i++)
if (getSubTypeTable(i).getSelectedRowKeys() != null) {
RichTable richTable = getSubTypeTable(i);
RowKeySet rowkeySet = richTable.getSelectedRowKeys();
rowkeySet.clear();
AdfFacesContext.getCurrentInstance().addPartialTarget(richTable);
}
}
And
private void clearAllExceptCurrent(int exceptControl) {
for (int i = 0; i < SUBTYPE_TABLES; i++)
if (i != exceptControl && getSubTypeTable(i).getSelectedRowKeys() != null) {
RichTable richTable = getSubTypeTable(i);
RowKeySet rowkeySet = richTable.getSelectedRowKeys();
rowkeySet.clear();
AdfFacesContext.getCurrentInstance().addPartialTarget(richTable);
}
}
I feel like I am writing duplicate redundant code here and will complicate maintenance in future . How can I improve this code and make it more object oriented ?
You can let clearAll() delegate (=> OOP pattern) to clearAllExceptCurrent() (=> improve code by removing duplicated code, make it more maintainable):
private void clearAll() {
clearAllExceptCurrent(-1);
}
The only difference between your two methods is the condition i != exceptControl in clearAllExceptCurrent(). By passing -1 this condition is always true and therefore effectively non-existent.
The bulk of the repeated code is the bit that clears the table. So how about:
private void clearTable(int id) {
if (getSubTypeTable(i).getSelectedRowKeys() != null) {
RichTable richTable = getSubTypeTable(i);
RowKeySet rowkeySet = richTable.getSelectedRowKeys();
rowkeySet.clear();
AdfFacesContext.getCurrentInstance().addPartialTarget(richTable);
}
}
Then:
private void clearAll() {
for (int i = 0; i < SUBTYPE_TABLES; i++) {
clearTable(i);
}
}
private void clearAllExceptCurrent(int exceptControl) {
for (int i = 0; i < SUBTYPE_TABLES; i++) {
if (i != exceptControl) {
clearTable(i)
}
}
}
EDIT: Moved if statement inside clearTable

Categories

Resources