Skip to content

Commit 4d85583

Browse files
committed
Table: add default methods for Collection/List API
1 parent fd3ea5a commit 4d85583

1 file changed

Lines changed: 147 additions & 16 deletions

File tree

src/main/java/org/scijava/table/Table.java

Lines changed: 147 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,15 @@
3030

3131
package org.scijava.table;
3232

33+
import java.lang.reflect.Array;
34+
import java.util.AbstractList;
3335
import java.util.ArrayList;
3436
import java.util.Collection;
3537
import java.util.Iterator;
3638
import java.util.List;
3739
import java.util.ListIterator;
3840
import java.util.Objects;
41+
import java.util.stream.Collectors;
3942

4043
/**
4144
* A table of values.
@@ -411,18 +414,27 @@ default boolean isEmpty() {
411414
* tested.
412415
*/
413416
@Override
414-
boolean contains(Object column);
417+
default boolean contains(final Object column) {
418+
return indexOf(column) >= 0;
419+
}
415420

416421
/** Returns an iterator over the columns in the table in proper sequence. */
417422
@Override
418-
Iterator<C> iterator();
423+
default Iterator<C> iterator() {
424+
return listIterator();
425+
}
419426

420427
/**
421428
* Returns an array containing all of the columns in the table in proper
422429
* sequence (from first to last column).
423430
*/
424431
@Override
425-
Object[] toArray();
432+
default Object[] toArray() {
433+
final Object[] columns = new Object[getColumnCount()];
434+
for (int c = 0; c < columns.length; c++)
435+
columns[c] = get(c);
436+
return columns;
437+
}
426438

427439
/**
428440
* Returns an array containing all of the column in the table in proper
@@ -433,7 +445,15 @@ default boolean isEmpty() {
433445
* list of columns.
434446
*/
435447
@Override
436-
<A> A[] toArray(A[] a);
448+
@SuppressWarnings("unchecked")
449+
default <A> A[] toArray(final A[] a) {
450+
final A[] columns = a.length >= getColumnCount() ? a : //
451+
(A[]) Array.newInstance(a.getClass().getComponentType(),
452+
getColumnCount());
453+
for (int c = 0; c < getColumnCount(); c++)
454+
columns[c] = (A) get(c);
455+
return columns;
456+
}
437457

438458
/**
439459
* Appends the specified column to the end of the table.
@@ -443,7 +463,10 @@ default boolean isEmpty() {
443463
* </p>
444464
*/
445465
@Override
446-
boolean add(C column);
466+
default boolean add(final C column) {
467+
add(getColumnCount(), column);
468+
return true;
469+
}
447470

448471
/**
449472
* Removes the first occurrence of the specified column from the table, if it
@@ -452,14 +475,24 @@ default boolean isEmpty() {
452475
* @return <tt>true</tt> if the table contained the specified column
453476
*/
454477
@Override
455-
boolean remove(Object column);
478+
default boolean remove(final Object column) {
479+
final int colIndex = indexOf(column);
480+
if (colIndex < 0) return false;
481+
remove(colIndex);
482+
return true;
483+
}
456484

457485
/**
458486
* Returns <tt>true</tt> if the table contains all of the columns of the
459487
* specified collection.
460488
*/
461489
@Override
462-
boolean containsAll(Collection<?> c);
490+
default boolean containsAll(final Collection<?> c) {
491+
for (final Object column : c) {
492+
if (!contains(column)) return false;
493+
}
494+
return true;
495+
}
463496

464497
/**
465498
* Appends all of the columns in the specified collection to the end of the
@@ -473,7 +506,12 @@ default boolean isEmpty() {
473506
* @return <tt>true</tt> if the table changed as a result of the call
474507
*/
475508
@Override
476-
boolean addAll(Collection<? extends C> c);
509+
default boolean addAll(final Collection<? extends C> c) {
510+
boolean changed = false;
511+
for (final C column : c)
512+
changed |= add(column);
513+
return changed;
514+
}
477515

478516
/**
479517
* Inserts all of the columns in the specified collection into this list at
@@ -486,7 +524,12 @@ default boolean isEmpty() {
486524
* @return <tt>true</tt> if the table changed as a result of the call
487525
*/
488526
@Override
489-
boolean addAll(int col, Collection<? extends C> c);
527+
default boolean addAll(final int col, final Collection<? extends C> c) {
528+
int index = col;
529+
for (final C column : c)
530+
add(index++, column);
531+
return c.size() > 0;
532+
}
490533

491534
/**
492535
* Removes from the table all of its columns that are contained in the
@@ -495,7 +538,12 @@ default boolean isEmpty() {
495538
* @return <tt>true</tt> if the table changed as a result of the call
496539
*/
497540
@Override
498-
boolean removeAll(Collection<?> c);
541+
default boolean removeAll(final Collection<?> c) {
542+
boolean changed = false;
543+
for (final Object column : c)
544+
changed |= remove(column);
545+
return changed;
546+
}
499547

500548
/**
501549
* Retains only the columns in the table that are contained in the specified
@@ -505,7 +553,12 @@ default boolean isEmpty() {
505553
* @return <tt>true</tt> if the table changed as a result of the call
506554
*/
507555
@Override
508-
boolean retainAll(Collection<?> c);
556+
default boolean retainAll(final Collection<?> c) {
557+
final List<?> absent = stream() //
558+
.filter(column -> !c.contains(column)) //
559+
.collect(Collectors.toList());
560+
return removeAll(absent);
561+
}
509562

510563
/**
511564
* Removes all data (including row and column headers) from the table. The
@@ -559,27 +612,93 @@ default boolean isEmpty() {
559612
* table, or -1 if the table does not contain the column.
560613
*/
561614
@Override
562-
int indexOf(Object column);
615+
default int indexOf(final Object column) {
616+
for (int c = 0; c < size(); c++)
617+
if (Objects.equals(get(c), column)) return c;
618+
return -1;
619+
}
563620

564621
/**
565622
* Returns the index of the last occurrence of the specified column in the
566623
* table, or -1 if the table does not contain the column.
567624
*/
568625
@Override
569-
int lastIndexOf(Object column);
626+
default int lastIndexOf(final Object column) {
627+
for (int c = size() - 1; c >= 0; c--)
628+
if (Objects.equals(get(c), column)) return c;
629+
return -1;
630+
}
570631

571632
/**
572633
* Returns a list iterator over the columns in the table (in proper sequence).
573634
*/
574635
@Override
575-
ListIterator<C> listIterator();
636+
default ListIterator<C> listIterator() {
637+
return listIterator(0);
638+
}
576639

577640
/**
578641
* Returns a list iterator of the columns in the table (in proper sequence),
579642
* starting at the specified position in the table.
580643
*/
581644
@Override
582-
ListIterator<C> listIterator(int col);
645+
default ListIterator<C> listIterator(final int col) {
646+
647+
return new ListIterator<C>() {
648+
649+
int last = -1;
650+
int c = col;
651+
652+
@Override
653+
public boolean hasNext() {
654+
return c < getColumnCount();
655+
}
656+
657+
@Override
658+
public C next() {
659+
return get(last = c++);
660+
}
661+
662+
@Override
663+
public boolean hasPrevious() {
664+
return c > 0;
665+
}
666+
667+
@Override
668+
public C previous() {
669+
return get(last = --c);
670+
}
671+
672+
@Override
673+
public int nextIndex() {
674+
return c;
675+
}
676+
677+
@Override
678+
public int previousIndex() {
679+
return c - 1;
680+
}
681+
682+
@Override
683+
public void remove() {
684+
if (last < 0) throw new IllegalStateException();
685+
Table.this.remove(last);
686+
last = -1;
687+
}
688+
689+
@Override
690+
public void set(final C e) {
691+
if (last < 0) throw new IllegalStateException();
692+
Table.this.set(last, e);
693+
}
694+
695+
@Override
696+
public void add(final C e) {
697+
Table.this.add(c++, e);
698+
last = -1;
699+
}
700+
};
701+
}
583702

584703
/**
585704
* Returns a view of the portion of the table between the specified
@@ -588,6 +707,18 @@ default boolean isEmpty() {
588707
* returned list are reflected in the table, and vice-versa.
589708
*/
590709
@Override
591-
List<C> subList(int fromCol, int toCol);
710+
default List<C> subList(final int fromCol, final int toCol) {
711+
return new AbstractList<C>() {
712+
713+
@Override
714+
public C get(final int index) {
715+
return Table.this.get(index + fromCol);
716+
}
592717

718+
@Override
719+
public int size() {
720+
return toCol - fromCol;
721+
}
722+
};
723+
}
593724
}

0 commit comments

Comments
 (0)