• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

link-intersystems / lis-commons / #252

22 Sep 2023 04:09PM UTC coverage: 89.886% (+0.08%) from 89.804%
#252

Pull #6

renelink
Added longest common sequence implementation.
Pull Request #6: Feature/sequence

106 of 106 new or added lines in 6 files covered. (100.0%)

7492 of 8335 relevant lines covered (89.89%)

0.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.06
/lis-commons-util/src/main/java/com/link_intersystems/util/Sequence.java
1
package com.link_intersystems.util;
2

3
import java.util.Iterator;
4
import java.util.ListIterator;
5
import java.util.NoSuchElementException;
6
import java.util.Spliterators;
7
import java.util.stream.Stream;
8
import java.util.stream.StreamSupport;
9

10
import static java.util.Objects.*;
11

12
public interface Sequence<E> extends Iterable<E> {
13

14
    public E elementAt(int index);
15

16
    public int length();
17

18
    default public Stream<E> stream() {
19
        if (length() == 0) {
1✔
20
            return Stream.empty();
×
21
        }
22

23

24
        return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator(), 0), false);
1✔
25
    }
26

27
    @Override
28
    default public Iterator<E> iterator() {
29
        return listIterator();
1✔
30
    }
31

32
    default public ListIterator<E> listIterator() {
33
        class SequenceListIterator<E> implements ListIterator<E> {
34

35
            private int nextIndex = 0;
1✔
36
            private Sequence<E> sequence;
37

38
            public SequenceListIterator(Sequence<E> sequence) {
1✔
39
                this.sequence = requireNonNull(sequence);
1✔
40
            }
1✔
41

42
            @Override
43
            public boolean hasNext() {
44
                return nextIndex < sequence.length();
1✔
45
            }
46

47
            @Override
48
            public E next() {
49
                if (hasNext()) {
1✔
50
                    return sequence.elementAt(nextIndex++);
1✔
51
                }
52

53
                throw new NoSuchElementException("No element available at index " + nextIndex);
1✔
54
            }
55

56
            @Override
57
            public boolean hasPrevious() {
58
                return nextIndex > 0;
1✔
59
            }
60

61
            @Override
62
            public E previous() {
63
                if (hasPrevious()) {
1✔
64
                    return sequence.elementAt(--nextIndex);
1✔
65
                }
66

67
                throw new NoSuchElementException("No element available before index " + nextIndex);
1✔
68
            }
69

70
            @Override
71
            public int nextIndex() {
72
                return nextIndex;
1✔
73
            }
74

75
            @Override
76
            public int previousIndex() {
77
                return nextIndex - 1;
1✔
78
            }
79

80
            @Override
81
            public void remove() {
82
                throw new UnsupportedOperationException("Elements can not be removed from a sequence");
1✔
83
            }
84

85
            @Override
86
            public void set(E element) {
87
                throw new UnsupportedOperationException("Elements can not be set on a sequence");
1✔
88
            }
89

90
            @Override
91
            public void add(E element) {
92
                throw new UnsupportedOperationException("Elements can not be added to a sequence");
1✔
93
            }
94
        }
95

96
        return new SequenceListIterator(this);
1✔
97
    }
98

99
    /**
100
     * Returns a {@code Sequence} that is a subsequence of this sequence.
101
     * The subsequence starts with the element at the specified index and
102
     * ends with the element at index {@code end - 1}.  The length
103
     * (elements) of the
104
     * returned sequence is {@code end - start}, so if {@code start == end}
105
     * then an empty sequence is returned.
106
     *
107
     * @param start the start index, inclusive
108
     * @param end   the end index, exclusive
109
     * @return the specified subsequence
110
     * @throws IndexOutOfBoundsException if {@code start} or {@code end} are negative,
111
     *                                   if {@code end} is greater than {@code length()},
112
     *                                   or if {@code start} is greater than {@code end}
113
     */
114
    default Sequence<E> subSequence(int start, int end) {
115
        class SubSequence<E> implements Sequence<E> {
116

117
            private Sequence<E> origSequence;
118
            private int start;
119
            private int end;
120

121
            public SubSequence(Sequence<E> origSequence, int start, int end) {
1✔
122
                if (start < 0 || start > end || end > origSequence.length()) {
1✔
123
                    throw new IllegalArgumentException("start and end must be within original sequence bounds: 0 - " + origSequence.length());
1✔
124
                }
125
                this.origSequence = requireNonNull(origSequence);
1✔
126
                this.start = start;
1✔
127
                this.end = end;
1✔
128
            }
1✔
129

130
            @Override
131
            public E elementAt(int index) {
132
                if (index < length()) {
1✔
133
                    return origSequence.elementAt(start + index);
1✔
134
                }
135

136
                throw new IndexOutOfBoundsException(index);
1✔
137
            }
138

139
            @Override
140
            public int length() {
141
                return end - start;
1✔
142
            }
143
        }
144

145
        return new SubSequence<>(this, start, end);
1✔
146
    }
147
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc