source: josm/trunk/src/org/openstreetmap/josm/tools/CopyList.java@ 2474

Last change on this file since 2474 was 1862, checked in by jttt, 15 years ago

Way refactoring - added method that will in future replace public field nodes

  • Property svn:mime-type set to text/plain
File size: 4.0 KB
Line 
1/*
2 * JOSMng - a Java Open Street Map editor, the next generation.
3 *
4 * Copyright (C) 2008 Petr Nejedly <P.Nejedly@sh.cvut.cz>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21package org.openstreetmap.josm.tools;
22
23import java.util.AbstractList;
24import java.util.RandomAccess;
25
26/**
27 * A List implementation initially based on given array, but never modifying
28 * the array directly. On the first modification, the implementation will
29 * create its own copy of the array, and after that it behaves mostly as
30 * an ArrayList.
31 *
32 * @author nenik
33 */
34public class CopyList<E> extends AbstractList<E> implements RandomAccess, Cloneable {
35 private E[] array;
36 private int size;
37 private boolean pristine;
38
39 /**
40 * Create a List over given array.
41 * @param array The initial List content. The array is never modified
42 * by the {@code CopyList}.
43 */
44 public CopyList(E[] array) {
45 this(array, array.length);
46 }
47
48 private CopyList(E[] array, int size) {
49 this.array = array;
50 this.size = size;
51 pristine = true;
52 }
53
54 // read-only access:
55 public @Override E get(int index) {
56 rangeCheck(index);
57 return array[index];
58 }
59
60 public @Override int size() {
61 return size;
62 }
63
64 // modification:
65 public @Override E set(int index, E element) {
66 rangeCheck(index);
67 changeCheck();
68
69 E old = array[index];
70 array[index] = element;
71 return old;
72 }
73
74 // full resizable semantics:
75 public @Override void add(int index, E element) {
76 // range check
77 ensureCapacity(size+1);
78 changeCheck();
79
80 System.arraycopy(array, index, array, index+1, size-index);
81 array[index] = element;
82 size++;
83 }
84
85 public @Override E remove(int index) {
86 rangeCheck(index);
87 changeCheck();
88
89 modCount++;
90 E element = array[index];
91 if (index < size-1) {
92 System.arraycopy(array, index+1, array, index, size-index-1);
93 } else {
94 array[index] = null;
95 }
96 size--;
97 return element;
98 }
99
100
101 // speed optimizations:
102 public @Override boolean add(E element) {
103 ensureCapacity(size+1);
104 changeCheck();
105 array[size++] = element;
106 return true;
107 }
108
109 public @Override void clear() {
110 modCount++;
111
112 // clean up the array
113 while (size > 0) array[--size] = null;
114 }
115
116 // helpers:
117 /**
118 * Returns another independent copy-on-write copy of this <tt>List</tt>
119 * instance. Neither the elements nor the backing storage are copied.
120 *
121 * @return a clone of this <tt>CopyList</tt> instance
122 */
123 public @Override Object clone() {
124 return new CopyList<E>(array, size);
125 }
126
127 private void rangeCheck(int index) {
128 if (index >= size || index < 0) throw new IndexOutOfBoundsException();
129 }
130
131 private void changeCheck() {
132 if (pristine) {
133 array = array.clone();
134 pristine = false;
135 }
136 }
137
138 @SuppressWarnings("unchecked")
139 private void ensureCapacity(int target) {
140 modCount++;
141 if (target > array.length) {
142 E[] old = array;
143
144 int newCapacity = Math.max(target, (array.length * 3)/2 + 1);
145 array = (E[]) new Object[newCapacity];
146 System.arraycopy(old, 0, array, 0, size);
147 pristine = false;
148 }
149 }
150}
Note: See TracBrowser for help on using the repository browser.