git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1087 379699f6-c40d-0410-875b-85095c16579ebranch_1_1
parent
48d5c63aec
commit
6786a3fa35
@ -1,785 +0,0 @@ |
||||
/* ClassInfo Copyright (C) 1998-1999 Jochen Hoenicke. |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation; either version 2, or (at your option) |
||||
* any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; see the file COPYING. If not, write to |
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
||||
* |
||||
* $Id$ |
||||
*/ |
||||
|
||||
package jode.bytecode; |
||||
import jode.GlobalOptions; |
||||
import java.io.DataInputStream; |
||||
import java.io.DataOutputStream; |
||||
import java.io.IOException; |
||||
import java.util.Enumeration; |
||||
///#ifdef JDK12
|
||||
///import java.util.Map;
|
||||
///import java.util.HashMap;
|
||||
///import java.lang.ref.WeakReference;
|
||||
///import java.lang.ref.ReferenceQueue;
|
||||
///#else
|
||||
import java.util.Hashtable; |
||||
///#endif
|
||||
import java.lang.reflect.Field; |
||||
import java.lang.reflect.Method; |
||||
import java.lang.reflect.Modifier; |
||||
|
||||
/** |
||||
* This class does represent a class similar to java.lang.Class. You |
||||
* can get the super class and the interfaces. |
||||
* |
||||
* The main difference to java.lang.Class is, that the objects are builded |
||||
* from a stream containing the .class file, and that it uses the |
||||
* <code>Type</code> to represent types instead of Class itself. |
||||
* |
||||
* @author Jochen Hoenicke |
||||
*/ |
||||
public class ClassInfo extends BinaryInfo { |
||||
|
||||
private static SearchPath classpath; |
||||
///#ifdef JDK12
|
||||
/// private static final Map classes = new HashMap();
|
||||
/// private static final ReferenceQueue queue = new ReferenceQueue();
|
||||
///#else
|
||||
private static final Hashtable classes = new Hashtable(); |
||||
///#endif
|
||||
|
||||
private int status = 0; |
||||
|
||||
private boolean modified = false; |
||||
|
||||
private int modifiers = -1; |
||||
private String name; |
||||
private ClassInfo superclass; |
||||
private ClassInfo[] interfaces; |
||||
private FieldInfo[] fields; |
||||
private MethodInfo[] methods; |
||||
private InnerClassInfo[] outerClasses; |
||||
private InnerClassInfo[] innerClasses; |
||||
private InnerClassInfo[] extraClasses; |
||||
private String sourceFile; |
||||
|
||||
public final static ClassInfo javaLangObject = forName("java.lang.Object"); |
||||
|
||||
public static void setClassPath(String path) { |
||||
classpath = new SearchPath(path); |
||||
///#ifdef JDK12
|
||||
/// java.lang.ref.Reference died;
|
||||
/// while ((died = queue.poll()) != null) {
|
||||
/// classes.values().remove(died);
|
||||
/// }
|
||||
/// Iterator i = classes.values().iterator();
|
||||
/// while (i.hasNext()) {
|
||||
/// ClassInfo ci = (ClassInfo) ((WeakReference)i.next()).get();
|
||||
/// if (ci == null) {
|
||||
/// i.remove();
|
||||
/// continue;
|
||||
/// }
|
||||
///#else
|
||||
Enumeration enum = classes.elements(); |
||||
while (enum.hasMoreElements()) { |
||||
ClassInfo ci = (ClassInfo) enum.nextElement(); |
||||
///#endif
|
||||
ci.status = 0; |
||||
ci.superclass = null; |
||||
ci.fields = null; |
||||
ci.interfaces = null; |
||||
ci.methods = null; |
||||
ci.removeAllAttributes(); |
||||
} |
||||
} |
||||
|
||||
public static boolean exists(String name) { |
||||
return classpath.exists(name.replace('.', '/') + ".class"); |
||||
} |
||||
|
||||
public static boolean isPackage(String name) { |
||||
return classpath.isDirectory(name.replace('.', '/')); |
||||
} |
||||
|
||||
public static Enumeration getClassesAndPackages(final String packageName) { |
||||
final Enumeration enum = |
||||
classpath.listFiles(packageName.replace('.','/')); |
||||
return new Enumeration() { |
||||
public boolean hasMoreElements() { |
||||
return enum.hasMoreElements(); |
||||
} |
||||
public Object nextElement() { |
||||
String name = (String) enum.nextElement(); |
||||
if (!name.endsWith(".class")) |
||||
// This is a package
|
||||
return name; |
||||
return name.substring(0, name.length()-6); |
||||
|
||||
} |
||||
}; |
||||
} |
||||
|
||||
public static ClassInfo forName(String name) { |
||||
if (name == null |
||||
|| name.indexOf(';') != -1 |
||||
|| name.indexOf('[') != -1 |
||||
|| name.indexOf('/') != -1) |
||||
throw new IllegalArgumentException("Illegal class name: "+name); |
||||
|
||||
///#ifdef JDK12
|
||||
/// java.lang.ref.Reference died;
|
||||
/// while ((died = queue.poll()) != null) {
|
||||
/// classes.values().remove(died);
|
||||
/// }
|
||||
/// WeakReference ref = (WeakReference) classes.get(name);
|
||||
/// ClassInfo clazz = (ref == null) ? null : (ClassInfo) ref.get();
|
||||
///#else
|
||||
ClassInfo clazz = (ClassInfo) classes.get(name); |
||||
///#endif
|
||||
if (clazz == null) { |
||||
clazz = new ClassInfo(name); |
||||
///#ifdef JDK12
|
||||
/// classes.put(name, new WeakReference(clazz, queue));
|
||||
///#else
|
||||
classes.put(name, clazz); |
||||
///#endif
|
||||
} |
||||
return clazz; |
||||
} |
||||
|
||||
private ClassInfo(String name) { |
||||
this.name = name; |
||||
} |
||||
|
||||
protected void readAttribute(String name, int length, |
||||
ConstantPool cp, |
||||
DataInputStream input, |
||||
int howMuch) throws IOException { |
||||
if ((howMuch & ALL_ATTRIBUTES) != 0 && name.equals("SourceFile")) { |
||||
if (length != 2) |
||||
throw new ClassFormatException("SourceFile attribute" |
||||
+ " has wrong length"); |
||||
sourceFile = cp.getUTF8(input.readUnsignedShort()); |
||||
} else if ((howMuch & (OUTERCLASSES | INNERCLASSES)) != 0 |
||||
&& name.equals("InnerClasses")) { |
||||
int count = input.readUnsignedShort(); |
||||
int innerCount = 0, outerCount = 0, extraCount = 0; |
||||
InnerClassInfo[] innerClassInfo = new InnerClassInfo[count]; |
||||
for (int i=0; i< count; i++) { |
||||
int innerIndex = input.readUnsignedShort(); |
||||
int outerIndex = input.readUnsignedShort(); |
||||
int nameIndex = input.readUnsignedShort(); |
||||
String inner = cp.getClassName(innerIndex); |
||||
String outer = |
||||
outerIndex != 0 ? cp.getClassName(outerIndex) : null; |
||||
String innername = |
||||
nameIndex != 0 ? cp.getUTF8(nameIndex) : null; |
||||
int access = input.readUnsignedShort(); |
||||
if (innername != null && innername.length() == 0) |
||||
innername = null; |
||||
InnerClassInfo ici = new InnerClassInfo |
||||
(inner, outer, innername, access); |
||||
|
||||
if (outer != null && outer.equals(getName()) |
||||
&& innername != null) |
||||
innerClassInfo[innerCount++] = ici; |
||||
else |
||||
innerClassInfo[count - (++extraCount)] = ici; |
||||
} |
||||
{ |
||||
String lastOuterName = getName(); |
||||
for (int i = count - extraCount; i < count; i++) { |
||||
InnerClassInfo ici = innerClassInfo[i]; |
||||
if (ici.inner.equals(lastOuterName)) { |
||||
for (int j = i; j > count - extraCount; j--) |
||||
innerClassInfo[j] = innerClassInfo[j-1]; |
||||
innerClassInfo[count-extraCount] = ici; |
||||
extraCount--; |
||||
outerCount++; |
||||
lastOuterName = ici.outer; |
||||
} |
||||
} |
||||
} |
||||
if (innerCount > 0) { |
||||
innerClasses = new InnerClassInfo[innerCount]; |
||||
System.arraycopy(innerClassInfo, 0, |
||||
innerClasses, 0, innerCount); |
||||
} else |
||||
innerClasses = null; |
||||
|
||||
if (outerCount > 0) { |
||||
outerClasses = new InnerClassInfo[outerCount]; |
||||
System.arraycopy(innerClassInfo, innerCount, |
||||
outerClasses, 0, outerCount); |
||||
} else |
||||
outerClasses = null; |
||||
|
||||
if (extraCount > 0) { |
||||
extraClasses = new InnerClassInfo[extraCount]; |
||||
System.arraycopy(innerClassInfo, innerCount + outerCount, |
||||
extraClasses, 0, extraCount); |
||||
} else |
||||
extraClasses = null; |
||||
|
||||
if (length != 2 + 8 * count) |
||||
throw new ClassFormatException |
||||
("InnerClasses attribute has wrong length"); |
||||
} else |
||||
super.readAttribute(name, length, cp, input, howMuch); |
||||
} |
||||
|
||||
public void read(DataInputStream input, int howMuch) throws IOException { |
||||
/* Since we have to read the whole class anyway, we load all |
||||
* info, that we may need later and that does not take much memory. |
||||
*/ |
||||
howMuch |= FIELDS | METHODS | HIERARCHY | INNERCLASSES | OUTERCLASSES; |
||||
howMuch &= ~status; |
||||
/* header */ |
||||
if (input.readInt() != 0xcafebabe) |
||||
throw new ClassFormatException("Wrong magic"); |
||||
if (input.readUnsignedShort() > 3) |
||||
throw new ClassFormatException("Wrong minor"); |
||||
if (input.readUnsignedShort() != 45) |
||||
throw new ClassFormatException("Wrong major"); |
||||
|
||||
/* constant pool */ |
||||
ConstantPool cpool = new ConstantPool(); |
||||
cpool.read(input); |
||||
|
||||
/* always read modifiers, name, super, ifaces */ |
||||
{ |
||||
modifiers = input.readUnsignedShort(); |
||||
String className = cpool.getClassName(input.readUnsignedShort()); |
||||
if (!name.equals(className)) |
||||
throw new ClassFormatException("wrong name " + className); |
||||
String superName = cpool.getClassName(input.readUnsignedShort()); |
||||
superclass = superName != null ? ClassInfo.forName(superName) : null; |
||||
int count = input.readUnsignedShort(); |
||||
interfaces = new ClassInfo[count]; |
||||
for (int i=0; i< count; i++) { |
||||
interfaces[i] = ClassInfo.forName |
||||
(cpool.getClassName(input.readUnsignedShort())); |
||||
} |
||||
status |= HIERARCHY; |
||||
} |
||||
|
||||
/* fields */ |
||||
if ((howMuch & (FIELDS | ALL_ATTRIBUTES)) != 0) { |
||||
int count = input.readUnsignedShort(); |
||||
if ((howMuch & FIELDS) != 0) |
||||
fields = new FieldInfo[count]; |
||||
for (int i=0; i< count; i++) { |
||||
if ((howMuch & FIELDS) != 0) |
||||
fields[i] = new FieldInfo(this); |
||||
fields[i].read(cpool, input, howMuch); |
||||
} |
||||
} else { |
||||
byte[] skipBuf = new byte[6]; |
||||
int count = input.readUnsignedShort(); |
||||
for (int i=0; i< count; i++) { |
||||
input.readFully(skipBuf); // modifier, name, type
|
||||
skipAttributes(input); |
||||
} |
||||
} |
||||
|
||||
/* methods */ |
||||
if ((howMuch & (METHODS | ALL_ATTRIBUTES)) != 0) { |
||||
int count = input.readUnsignedShort(); |
||||
if ((howMuch & METHODS) != 0) |
||||
methods = new MethodInfo[count]; |
||||
for (int i=0; i< count; i++) { |
||||
if ((howMuch & METHODS) != 0) |
||||
methods[i] = new MethodInfo(this); |
||||
methods[i].read(cpool, input, howMuch); |
||||
} |
||||
} else { |
||||
byte[] skipBuf = new byte[6]; |
||||
int count = input.readUnsignedShort(); |
||||
for (int i=0; i< count; i++) { |
||||
input.readFully(skipBuf); // modifier, name, type
|
||||
skipAttributes(input); |
||||
} |
||||
} |
||||
|
||||
/* attributes */ |
||||
readAttributes(cpool, input, howMuch); |
||||
status |= howMuch; |
||||
} |
||||
|
||||
public void reserveSmallConstants(GrowableConstantPool gcp) { |
||||
for (int i=0; i < fields.length; i++) |
||||
fields[i].reserveSmallConstants(gcp); |
||||
|
||||
for (int i=0; i < methods.length; i++) |
||||
methods[i].reserveSmallConstants(gcp); |
||||
} |
||||
|
||||
public void prepareWriting(GrowableConstantPool gcp) { |
||||
gcp.putClassName(name); |
||||
gcp.putClassName(superclass.getName()); |
||||
for (int i=0; i < interfaces.length; i++) |
||||
gcp.putClassName(interfaces[i].getName()); |
||||
|
||||
for (int i=0; i < fields.length; i++) |
||||
fields[i].prepareWriting(gcp); |
||||
|
||||
for (int i=0; i < methods.length; i++) |
||||
methods[i].prepareWriting(gcp); |
||||
|
||||
if (sourceFile != null) { |
||||
gcp.putUTF8("SourceFile"); |
||||
gcp.putUTF8(sourceFile); |
||||
} |
||||
if (outerClasses != null || innerClasses != null |
||||
|| extraClasses != null) { |
||||
gcp.putUTF8("InnerClasses"); |
||||
int outerCount = outerClasses != null ? outerClasses.length : 0; |
||||
for (int i=outerCount; i-- > 0;) { |
||||
gcp.putClassName(outerClasses[i].inner); |
||||
if (outerClasses[i].outer != null) |
||||
gcp.putClassName(outerClasses[i].outer); |
||||
if (outerClasses[i].name != null) |
||||
gcp.putUTF8(outerClasses[i].name); |
||||
} |
||||
int innerCount = innerClasses != null ? innerClasses.length : 0; |
||||
for (int i=0; i< innerCount; i++) { |
||||
gcp.putClassName(innerClasses[i].inner); |
||||
if (innerClasses[i].outer != null) |
||||
gcp.putClassName(innerClasses[i].outer); |
||||
if (innerClasses[i].name != null) |
||||
gcp.putUTF8(innerClasses[i].name); |
||||
} |
||||
int extraCount = extraClasses != null ? extraClasses.length : 0; |
||||
for (int i=0; i< extraCount; i++) { |
||||
gcp.putClassName(extraClasses[i].inner); |
||||
if (extraClasses[i].outer != null) |
||||
gcp.putClassName(extraClasses[i].outer); |
||||
if (extraClasses[i].name != null) |
||||
gcp.putUTF8(extraClasses[i].name); |
||||
} |
||||
} |
||||
prepareAttributes(gcp); |
||||
} |
||||
|
||||
protected int getKnownAttributeCount() { |
||||
int count = 0; |
||||
if (sourceFile != null) |
||||
count++; |
||||
if (innerClasses != null || outerClasses != null |
||||
|| extraClasses != null) |
||||
count++; |
||||
return count; |
||||
} |
||||
|
||||
public void writeKnownAttributes(GrowableConstantPool gcp, |
||||
DataOutputStream output) |
||||
throws IOException { |
||||
if (sourceFile != null) { |
||||
output.writeShort(gcp.putUTF8("SourceFile")); |
||||
output.writeInt(2); |
||||
output.writeShort(gcp.putUTF8(sourceFile)); |
||||
} |
||||
if (outerClasses != null || innerClasses != null |
||||
|| extraClasses != null) { |
||||
output.writeShort(gcp.putUTF8("InnerClasses")); |
||||
int outerCount = (outerClasses != null) ? outerClasses.length : 0; |
||||
int innerCount = (innerClasses != null) ? innerClasses.length : 0; |
||||
int extraCount = (extraClasses != null) ? extraClasses.length : 0; |
||||
int count = outerCount + innerCount + extraCount; |
||||
output.writeInt(2 + count * 8); |
||||
output.writeShort(count); |
||||
for (int i=outerCount; i-- > 0; ) { |
||||
output.writeShort(gcp.putClassName(outerClasses[i].inner)); |
||||
output.writeShort(outerClasses[i].outer != null ? |
||||
gcp.putClassName(outerClasses[i].outer) : 0); |
||||
output.writeShort(outerClasses[i].name != null ? |
||||
gcp.putUTF8(outerClasses[i].name) : 0); |
||||
output.writeShort(outerClasses[i].modifiers); |
||||
} |
||||
for (int i=0; i< innerCount; i++) { |
||||
output.writeShort(gcp.putClassName(innerClasses[i].inner)); |
||||
output.writeShort(innerClasses[i].outer != null ? |
||||
gcp.putClassName(innerClasses[i].outer) : 0); |
||||
output.writeShort(innerClasses[i].name != null ? |
||||
gcp.putUTF8(innerClasses[i].name) : 0); |
||||
output.writeShort(innerClasses[i].modifiers); |
||||
} |
||||
for (int i=0; i< extraCount; i++) { |
||||
output.writeShort(gcp.putClassName(extraClasses[i].inner)); |
||||
output.writeShort(extraClasses[i].outer != null ? |
||||
gcp.putClassName(extraClasses[i].outer) : 0); |
||||
output.writeShort(extraClasses[i].name != null ? |
||||
gcp.putUTF8(extraClasses[i].name) : 0); |
||||
output.writeShort(extraClasses[i].modifiers); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public void write(DataOutputStream out) throws IOException { |
||||
GrowableConstantPool gcp = new GrowableConstantPool(); |
||||
reserveSmallConstants(gcp); |
||||
prepareWriting(gcp); |
||||
|
||||
out.writeInt(0xcafebabe); |
||||
out.writeShort(3); |
||||
out.writeShort(45); |
||||
gcp.write(out); |
||||
|
||||
out.writeShort(modifiers); |
||||
out.writeShort(gcp.putClassName(name)); |
||||
out.writeShort(gcp.putClassName(superclass.getName())); |
||||
out.writeShort(interfaces.length); |
||||
for (int i=0; i < interfaces.length; i++) |
||||
out.writeShort(gcp.putClassName(interfaces[i].getName())); |
||||
|
||||
out.writeShort(fields.length); |
||||
for (int i=0; i < fields.length; i++) |
||||
fields[i].write(gcp, out); |
||||
|
||||
out.writeShort(methods.length); |
||||
for (int i=0; i < methods.length; i++) |
||||
methods[i].write(gcp, out); |
||||
|
||||
writeAttributes(gcp, out); |
||||
} |
||||
|
||||
public void loadInfoReflection(Class clazz, int howMuch) |
||||
throws SecurityException { |
||||
if ((howMuch & HIERARCHY) != 0) { |
||||
modifiers = clazz.getModifiers(); |
||||
if (clazz.getSuperclass() == null) |
||||
superclass = null; |
||||
else |
||||
superclass = ClassInfo.forName |
||||
(clazz.getSuperclass().getName()); |
||||
Class[] ifaces = clazz.getInterfaces(); |
||||
interfaces = new ClassInfo[ifaces.length]; |
||||
for (int i=0; i<ifaces.length; i++) |
||||
interfaces[i] = ClassInfo.forName(ifaces[i].getName()); |
||||
status |= HIERARCHY; |
||||
} |
||||
if ((howMuch & FIELDS) != 0 && fields == null) { |
||||
Field[] fs; |
||||
try { |
||||
fs = clazz.getDeclaredFields(); |
||||
} catch (SecurityException ex) { |
||||
fs = clazz.getFields(); |
||||
GlobalOptions.err.println |
||||
("Could only get public fields of class " |
||||
+ name + "."); |
||||
} |
||||
fields = new FieldInfo[fs.length]; |
||||
for (int i = fs.length; --i >= 0; ) { |
||||
String type = TypeSignature.getSignature(fs[i].getType()); |
||||
fields[i] = new FieldInfo |
||||
(this, fs[i].getName(), type, fs[i].getModifiers()); |
||||
} |
||||
} |
||||
if ((howMuch & METHODS) != 0 && methods == null) { |
||||
Method[] ms; |
||||
try { |
||||
ms = clazz.getDeclaredMethods(); |
||||
} catch (SecurityException ex) { |
||||
ms = clazz.getMethods(); |
||||
GlobalOptions.err.println |
||||
("Could only get public methods of class " |
||||
+ name + "."); |
||||
} |
||||
methods = new MethodInfo[ms.length]; |
||||
for (int i = ms.length; --i >= 0; ) { |
||||
String type = TypeSignature.getSignature |
||||
(ms[i].getParameterTypes(), ms[i].getReturnType()); |
||||
methods[i] = new MethodInfo |
||||
(this, ms[i].getName(), type, ms[i].getModifiers()); |
||||
} |
||||
} |
||||
if ((howMuch & INNERCLASSES) != 0 && innerClasses == null) { |
||||
Class[] is; |
||||
try { |
||||
is = clazz.getDeclaredClasses(); |
||||
} catch (SecurityException ex) { |
||||
is = clazz.getClasses(); |
||||
GlobalOptions.err.println |
||||
("Could only get public methods of class " |
||||
+ name + "."); |
||||
} |
||||
if (is.length > 0) { |
||||
innerClasses = new InnerClassInfo[is.length]; |
||||
for (int i = is.length; --i >= 0; ) { |
||||
String inner = is[i].getName(); |
||||
int dollar = inner.lastIndexOf('$'); |
||||
String name = inner.substring(dollar+1); |
||||
innerClasses[i] = new InnerClassInfo |
||||
(inner, getName(), name, is[i].getModifiers()); |
||||
} |
||||
} |
||||
} |
||||
if ((howMuch & OUTERCLASSES) != 0 && outerClasses == null) { |
||||
int count = 0; |
||||
Class declarer = clazz.getDeclaringClass(); |
||||
while (declarer != null) { |
||||
count++; |
||||
declarer = declarer.getDeclaringClass(); |
||||
} |
||||
if (count > 0) { |
||||
outerClasses = new InnerClassInfo[count]; |
||||
Class current = clazz; |
||||
for (int i = 0; i < count; i++) { |
||||
declarer = current.getDeclaringClass(); |
||||
String name = current.getName(); |
||||
int dollar = name.lastIndexOf('$'); |
||||
outerClasses[i] = new InnerClassInfo |
||||
(name, declarer.getName(), |
||||
name.substring(dollar+1), current.getModifiers()); |
||||
current = declarer; |
||||
} |
||||
} |
||||
} |
||||
status |= howMuch; |
||||
} |
||||
|
||||
public void loadInfo(int howMuch) { |
||||
if ((status & howMuch) == howMuch) |
||||
return; |
||||
if (modified) { |
||||
System.err.println("Allocating info 0x" |
||||
+ Integer.toHexString(howMuch) |
||||
+ " (status 0x" + Integer.toHexString(status) |
||||
+ ") in class " + this); |
||||
Thread.dumpStack(); |
||||
return; |
||||
} |
||||
try { |
||||
DataInputStream input = |
||||
new DataInputStream(classpath.getFile(name.replace('.', '/') |
||||
+ ".class")); |
||||
read(input, howMuch); |
||||
|
||||
} catch (IOException ex) { |
||||
String message = ex.getMessage(); |
||||
if ((howMuch & ~(FIELDS|METHODS|HIERARCHY |
||||
|INNERCLASSES|OUTERCLASSES)) != 0) { |
||||
GlobalOptions.err.println |
||||
("Can't read class " + name + "."); |
||||
ex.printStackTrace(GlobalOptions.err); |
||||
throw new NoClassDefFoundError(name); |
||||
} |
||||
// Try getting the info through the reflection interface
|
||||
// instead.
|
||||
Class clazz = null; |
||||
try { |
||||
clazz = Class.forName(name); |
||||
} catch (ClassNotFoundException ex2) { |
||||
} catch (NoClassDefFoundError ex2) { |
||||
} |
||||
try { |
||||
if (clazz != null) { |
||||
loadInfoReflection(clazz, howMuch); |
||||
return; |
||||
} |
||||
} catch (SecurityException ex2) { |
||||
GlobalOptions.err.println |
||||
(ex2+" while collecting info about class " + name + "."); |
||||
} |
||||
|
||||
// Give a warning and ``guess'' the hierarchie, methods etc.
|
||||
GlobalOptions.err.println |
||||
("Can't read class " + name + ", types may be incorrect. (" |
||||
+ ex.getClass().getName() |
||||
+ (message != null ? ": " + message : "") + ")"); |
||||
|
||||
if ((howMuch & HIERARCHY) != 0) { |
||||
modifiers = Modifier.PUBLIC; |
||||
if (name.equals("java.lang.Object")) |
||||
superclass = null; |
||||
else |
||||
superclass = javaLangObject; |
||||
interfaces = new ClassInfo[0]; |
||||
} |
||||
if ((howMuch & METHODS) != 0) |
||||
methods = new MethodInfo[0]; |
||||
if ((howMuch & FIELDS) != 0) |
||||
fields = new FieldInfo[0]; |
||||
status |= howMuch; |
||||
} |
||||
} |
||||
|
||||
public String getName() { |
||||
return name; |
||||
} |
||||
|
||||
public String getJavaName() { |
||||
/* Don't load attributes for class names not containing a |
||||
* dollar sign. |
||||
*/ |
||||
if (name.indexOf('$') == -1) |
||||
return getName(); |
||||
if (getOuterClasses() != null) { |
||||
int last = outerClasses.length-1; |
||||
StringBuffer sb = |
||||
new StringBuffer(outerClasses[last].outer != null |
||||
? outerClasses[last].outer : "METHOD"); |
||||
for (int i=last; i >= 0; i--) |
||||
sb.append(".").append(outerClasses[i].name != null |
||||
? outerClasses[i].name : "ANONYMOUS"); |
||||
return sb.toString(); |
||||
} |
||||
return getName(); |
||||
} |
||||
|
||||
public ClassInfo getSuperclass() { |
||||
if ((status & HIERARCHY) == 0) |
||||
loadInfo(HIERARCHY); |
||||
return superclass; |
||||
} |
||||
|
||||
public ClassInfo[] getInterfaces() { |
||||
if ((status & HIERARCHY) == 0) |
||||
loadInfo(HIERARCHY); |
||||
return interfaces; |
||||
} |
||||
|
||||
public int getModifiers() { |
||||
if ((status & HIERARCHY) == 0) |
||||
loadInfo(HIERARCHY); |
||||
return modifiers; |
||||
} |
||||
|
||||
public boolean isInterface() { |
||||
return Modifier.isInterface(getModifiers()); |
||||
} |
||||
|
||||
public FieldInfo findField(String name, String typeSig) { |
||||
if ((status & FIELDS) == 0) |
||||
loadInfo(FIELDS); |
||||
for (int i=0; i< fields.length; i++) |
||||
if (fields[i].getName().equals(name) |
||||
&& fields[i].getType().equals(typeSig)) |
||||
return fields[i]; |
||||
return null; |
||||
} |
||||
|
||||
public MethodInfo findMethod(String name, String typeSig) { |
||||
if ((status & METHODS) == 0) |
||||
loadInfo(METHODS); |
||||
for (int i=0; i< methods.length; i++) |
||||
if (methods[i].getName().equals(name) |
||||
&& methods[i].getType().equals(typeSig)) |
||||
return methods[i]; |
||||
return null; |
||||
} |
||||
|
||||
public MethodInfo[] getMethods() { |
||||
if ((status & METHODS) == 0) |
||||
loadInfo(METHODS); |
||||
return methods; |
||||
} |
||||
|
||||
public FieldInfo[] getFields() { |
||||
if ((status & FIELDS) == 0) |
||||
loadInfo(FIELDS); |
||||
return fields; |
||||
} |
||||
|
||||
public InnerClassInfo[] getOuterClasses() { |
||||
if ((status & OUTERCLASSES) == 0) |
||||
loadInfo(OUTERCLASSES); |
||||
return outerClasses; |
||||
} |
||||
|
||||
public InnerClassInfo[] getInnerClasses() { |
||||
if ((status & INNERCLASSES) == 0) |
||||
loadInfo(INNERCLASSES); |
||||
return innerClasses; |
||||
} |
||||
|
||||
public InnerClassInfo[] getExtraClasses() { |
||||
if ((status & INNERCLASSES) == 0) |
||||
loadInfo(INNERCLASSES); |
||||
return extraClasses; |
||||
} |
||||
|
||||
public String getSourceFile() { |
||||
return sourceFile; |
||||
} |
||||
|
||||
public void setName(String newName) { |
||||
name = newName; |
||||
modified = true; |
||||
} |
||||
|
||||
public void setSuperclass(ClassInfo newSuper) { |
||||
superclass = newSuper; |
||||
modified = true; |
||||
} |
||||
|
||||
public void setInterfaces(ClassInfo[] newIfaces) { |
||||
interfaces = newIfaces; |
||||
modified = true; |
||||
} |
||||
|
||||
public void setModifiers(int newModifiers) { |
||||
modifiers = newModifiers; |
||||
modified = true; |
||||
} |
||||
|
||||
public void setMethods(MethodInfo[] mi) { |
||||
methods = mi; |
||||
modified = true; |
||||
} |
||||
|
||||
public void setFields(FieldInfo[] fi) { |
||||
fields = fi; |
||||
modified = true; |
||||
} |
||||
|
||||
public void setOuterClasses(InnerClassInfo[] oc) { |
||||
outerClasses = oc; |
||||
modified = true; |
||||
} |
||||
|
||||
public void setInnerClasses(InnerClassInfo[] ic) { |
||||
innerClasses = ic; |
||||
modified = true; |
||||
} |
||||
|
||||
public void setExtraClasses(InnerClassInfo[] ec) { |
||||
extraClasses = ec; |
||||
modified = true; |
||||
} |
||||
|
||||
public void setSourceFile(String newSource) { |
||||
sourceFile = newSource; |
||||
modified = true; |
||||
} |
||||
|
||||
public boolean superClassOf(ClassInfo son) { |
||||
while (son != this && son != null) { |
||||
son = son.getSuperclass(); |
||||
} |
||||
return son == this; |
||||
} |
||||
|
||||
public boolean implementedBy(ClassInfo clazz) { |
||||
while (clazz != this && clazz != null) { |
||||
ClassInfo[] ifaces = clazz.getInterfaces(); |
||||
for (int i=0; i< ifaces.length; i++) { |
||||
if (implementedBy(ifaces[i])) |
||||
return true; |
||||
} |
||||
clazz = clazz.getSuperclass(); |
||||
} |
||||
return clazz == this; |
||||
} |
||||
|
||||
public String toString() { |
||||
return name; |
||||
} |
||||
} |
@ -1,337 +0,0 @@ |
||||
// This interface is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AbstractCollection.java -- Abstract implementation of most of Collection
|
||||
//
|
||||
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package jode.util; |
||||
|
||||
import java.lang.reflect.Array; |
||||
|
||||
/** |
||||
* A basic implementation of most of the methods in the Collection interface to |
||||
* make it easier to create a collection. To create an unmodifiable Collection, |
||||
* just subclass AbstractCollection and provide implementations of the |
||||
* iterator() and size() methods. The Iterator returned by iterator() need only |
||||
* provide implementations of hasNext() and next() (that is, it may throw an |
||||
* UnsupportedOperationException if remove() is called). To create a modifiable |
||||
* Collection, you must in addition provide an implementation of the |
||||
* add(Object) method and the Iterator returned by iterator() must provide an |
||||
* implementation of remove(). Other methods should be overridden if the |
||||
* backing data structure allows for a more efficient implementation. The |
||||
* precise implementation used by AbstractCollection is documented, so that |
||||
* subclasses can tell which methods could be implemented more efficiently. |
||||
*/ |
||||
public abstract class AbstractCollection implements Collection { |
||||
|
||||
/** |
||||
* Return an Iterator over this collection. The iterator must provide the |
||||
* hasNext and next methods and should in addition provide remove if the |
||||
* collection is modifiable. |
||||
*/ |
||||
public abstract Iterator iterator(); |
||||
|
||||
/** |
||||
* Return the number of elements in this collection. |
||||
*/ |
||||
public abstract int size(); |
||||
|
||||
/** |
||||
* Add an object to the collection. This implementation always throws an |
||||
* UnsupportedOperationException - it should be overridden if the collection |
||||
* is to be modifiable. |
||||
* |
||||
* @param o the object to add |
||||
* @return true if the add operation caused the Collection to change |
||||
* @exception UnsupportedOperationException if the add operation is not |
||||
* supported on this collection |
||||
*/ |
||||
public boolean add(Object o) { |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
/** |
||||
* Add all the elements of a given collection to this collection. This |
||||
* implementation obtains an Iterator over the given collection and iterates |
||||
* over it, adding each element with the add(Object) method (thus this method |
||||
* will fail with an UnsupportedOperationException if the add method does). |
||||
* |
||||
* @param c the collection to add the elements of to this collection |
||||
* @return true if the add operation caused the Collection to change |
||||
* @exception UnsupportedOperationException if the add operation is not |
||||
* supported on this collection |
||||
*/ |
||||
public boolean addAll(Collection c) { |
||||
Iterator i = c.iterator(); |
||||
boolean modified = false; |
||||
while (i.hasNext()) { |
||||
modified |= add(i.next()); |
||||
} |
||||
return modified; |
||||
} |
||||
|
||||
/** |
||||
* Remove all elements from the collection. This implementation obtains an |
||||
* iterator over the collection and calls next and remove on it repeatedly |
||||
* (thus this method will fail with an UnsupportedOperationException if the |
||||
* Iterator's remove method does) until there are no more elements to remove. |
||||
* Many implementations will have a faster way of doing this. |
||||
* |
||||
* @exception UnsupportedOperationException if the Iterator returned by |
||||
* iterator does not provide an implementation of remove |
||||
*/ |
||||
public void clear() { |
||||
Iterator i = iterator(); |
||||
while (i.hasNext()) { |
||||
i.next(); |
||||
i.remove(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Test whether this collection contains a given object. That is, if the |
||||
* collection has an element e such that (o == null ? e == null : |
||||
* o.equals(e)). This implementation obtains an iterator over the collection |
||||
* and iterates over it, testing each element for equality with the given |
||||
* object. If it is equal, true is returned. Otherwise false is returned when |
||||
* the end of the collection is reached. |
||||
* |
||||
* @param o the object to remove from this collection |
||||
* @return true if this collection contains an object equal to o |
||||
*/ |
||||
public boolean contains(Object o) { |
||||
Iterator i = iterator(); |
||||
|
||||
// This looks crazily inefficient, but it takes the test o==null outside
|
||||
// the loop, saving time, and also saves needing to store the result of
|
||||
// i.next() each time.
|
||||
if (o == null) { |
||||
while (i.hasNext()) { |
||||
if (i.next() == null) { |
||||
return true; |
||||
} |
||||
} |
||||
} else { |
||||
while (i.hasNext()) { |
||||
if (o.equals(i.next())) { |
||||
return true; |
||||
} |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Tests whether this collection contains all the elements in a given |
||||
* collection. This implementation iterates over the given collection, |
||||
* testing whether each element is contained in this collection. If any one |
||||
* is not, false is returned. Otherwise true is returned. |
||||
* |
||||
* @param c the collection to test against |
||||
* @return true if this collection contains all the elements in the given |
||||
* collection |
||||
*/ |
||||
public boolean containsAll(Collection c) { |
||||
Iterator i = c.iterator(); |
||||
while (i.hasNext()) { |
||||
if (!contains(i.next())) { |
||||
return false; |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* Test whether this collection is empty. This implementation returns |
||||
* size() == 0. |
||||
* |
||||
* @return true if this collection is empty. |
||||
*/ |
||||
public boolean isEmpty() { |
||||
return size() == 0; |
||||
} |
||||
|
||||
/** |
||||
* Remove a single instance of an object from this collection. That is, |
||||
* remove one element e such that (o == null ? e == null : o.equals(e)), if |
||||
* such an element exists. This implementation obtains an iterator over the |
||||
* collection and iterates over it, testing each element for equality with |
||||
* the given object. If it is equal, it is removed by the iterator's remove |
||||
* method (thus this method will fail with an UnsupportedOperationException |
||||
* if the Iterator's remove method does). After the first element has been |
||||
* removed, true is returned; if the end of the collection is reached, false |
||||
* is returned. |
||||
* |
||||
* @param o the object to remove from this collection |
||||
* @return true if the remove operation caused the Collection to change, or |
||||
* equivalently if the collection did contain o. |
||||
* @exception UnsupportedOperationException if this collection's Iterator |
||||
* does not support the remove method |
||||
*/ |
||||
public boolean remove(Object o) { |
||||
Iterator i = iterator(); |
||||
|
||||
// This looks crazily inefficient, but it takes the test o==null outside
|
||||
// the loop, saving time, and also saves needing to store the result of
|
||||
// i.next() each time.
|
||||
if (o == null) { |
||||
while (i.hasNext()) { |
||||
if (i.next() == null) { |
||||
i.remove(); |
||||
return true; |
||||
} |
||||
} |
||||
} else { |
||||
while (i.hasNext()) { |
||||
if (o.equals(i.next())) { |
||||
i.remove(); |
||||
return true; |
||||
} |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Remove from this collection all its elements that are contained in a given |
||||
* collection. This implementation iterates over this collection, and for |
||||
* each element tests if it is contained in the given collection. If so, it |
||||
* is removed by the Iterator's remove method (thus this method will fail |
||||
* with an UnsupportedOperationException if the Iterator's remove method |
||||
* does). |
||||
* |
||||
* @param c the collection to remove the elements of |
||||
* @return true if the remove operation caused the Collection to change |
||||
* @exception UnsupportedOperationException if this collection's Iterator |
||||
* does not support the remove method |
||||
*/ |
||||
public boolean removeAll(Collection c) { |
||||
Iterator i = iterator(); |
||||
boolean changed = false; |
||||
while (i.hasNext()) { |
||||
if (c.contains(i.next())) { |
||||
i.remove(); |
||||
changed = true; |
||||
} |
||||
} |
||||
return changed; |
||||
} |
||||
|
||||
/** |
||||
* Remove from this collection all its elements that are not contained in a |
||||
* given collection. This implementation iterates over this collection, and |
||||
* for each element tests if it is contained in the given collection. If not, |
||||
* it is removed by the Iterator's remove method (thus this method will fail |
||||
* with an UnsupportedOperationException if the Iterator's remove method |
||||
* does). |
||||
* |
||||
* @param c the collection to retain the elements of |
||||
* @return true if the remove operation caused the Collection to change |
||||
* @exception UnsupportedOperationException if this collection's Iterator |
||||
* does not support the remove method |
||||
*/ |
||||
public boolean retainAll(Collection c) { |
||||
Iterator i = iterator(); |
||||
boolean changed = false; |
||||
while (i.hasNext()) { |
||||
if (!c.contains(i.next())) { |
||||
i.remove(); |
||||
changed = true; |
||||
} |
||||
} |
||||
return changed; |
||||
} |
||||
|
||||
/** |
||||
* Return an array containing the elements of this collection. This |
||||
* implementation creates an Object array of size size() and then iterates |
||||
* over the collection, setting each element of the array from the value |
||||
* returned by the iterator. |
||||
* |
||||
* @return an array containing the elements of this collection |
||||
*/ |
||||
public Object[] toArray() { |
||||
Object[] a = new Object[size()]; |
||||
Iterator i = iterator(); |
||||
for (int pos = 0; pos < a.length; pos++) { |
||||
a[pos] = i.next(); |
||||
} |
||||
return a; |
||||
} |
||||
|
||||
/** |
||||
* Copy the collection into a given array if it will fit, or into a |
||||
* dynamically created array of the same run-time type as the given array if |
||||
* not. If there is space remaining in the array, the first element after the |
||||
* end of the collection is set to null (this is only useful if the |
||||
* collection is known to contain no null elements, however). This |
||||
* implementation first tests whether the given array is large enough to hold |
||||
* all the elements of the collection. If not, the reflection API is used to |
||||
* allocate a new array of the same run-time type. Next an iterator is |
||||
* obtained over the collection and the elements are placed in the array as |
||||
* they are returned by the iterator. Finally the first spare element, if |
||||
* any, of the array is set to null, and the created array is returned. |
||||
* |
||||
* @param a the array to copy into, or of the correct run-time type |
||||
* @return the array that was produced |
||||
* @exception ClassCastException if the type of the array precludes holding |
||||
* one of the elements of the Collection |
||||
*/ |
||||
public Object[] toArray(Object[] a) { |
||||
final int n = size(); |
||||
if (a.length < n) { |
||||
a = (Object[])Array.newInstance(a.getClass().getComponentType(), n); |
||||
} |
||||
Iterator i = iterator(); |
||||
for (int pos = 0; pos < n; pos++) { |
||||
a[pos] = i.next(); |
||||
} |
||||
if (a.length > n) { |
||||
a[n] = null; |
||||
} |
||||
return a; |
||||
} |
||||
|
||||
/** |
||||
* Creates a String representation of the Collection. The string returned is |
||||
* of the form "[a, b, ...]" where a and b etc are the results of calling |
||||
* toString on the elements of the collection. This implementation obtains an |
||||
* Iterator over the Collection and adds each element to a StringBuffer as it |
||||
* is returned by the iterator. |
||||
* |
||||
* @return a String representation of the Collection |
||||
*/ |
||||
public String toString() { |
||||
StringBuffer s = new StringBuffer(); |
||||
s.append('['); |
||||
Iterator i = iterator(); |
||||
boolean more = i.hasNext(); |
||||
while(more) { |
||||
s.append(i.next()); |
||||
if (more = i.hasNext()) { |
||||
s.append(", "); |
||||
} |
||||
} |
||||
s.append(']'); |
||||
return s.toString(); |
||||
} |
||||
} |
@ -1,560 +0,0 @@ |
||||
// This interface is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AbstractList.java -- Abstract implementation of most of List
|
||||
//
|
||||
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TO DO:
|
||||
// ~ Doc comments for almost everything.
|
||||
// ~ Better general commenting
|
||||
|
||||
package jode.util; |
||||
import java.util.NoSuchElementException; |
||||
|
||||
/** |
||||
* A basic implementation of most of the methods in the List interface to make |
||||
* it easier to create a List based on a random-access data structure. To |
||||
* create an unmodifiable list, it is only necessary to override the size() and |
||||
* get(int) methods (this contrasts with all other abstract collection classes |
||||
* which require an iterator to be provided). To make the list modifiable, the |
||||
* set(int, Object) method should also be overridden, and to make the list |
||||
* resizable, the add(int, Object) and remove(int) methods should be overridden |
||||
* too. Other methods should be overridden if the backing data structure allows |
||||
* for a more efficient implementation. The precise implementation used by |
||||
* AbstractList is documented, so that subclasses can tell which methods could |
||||
* be implemented more efficiently. |
||||
*/ |
||||
public abstract class AbstractList extends AbstractCollection implements List { |
||||
|
||||
/** |
||||
* A count of the number of structural modifications that have been made to |
||||
* the list (that is, insertions and removals). |
||||
*/ |
||||
protected transient int modCount = 0; |
||||
|
||||
public abstract Object get(int index); |
||||
|
||||
public void add(int index, Object o) { |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
public boolean add(Object o) { |
||||
add(size(), o); |
||||
return true; |
||||
} |
||||
|
||||
public boolean addAll(int index, Collection c) { |
||||
Iterator i = c.iterator(); |
||||
if (i.hasNext()) { |
||||
do { |
||||
add(index++, i.next()); |
||||
} while (i.hasNext()); |
||||
return true; |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public void clear() { |
||||
removeRange(0, size()); |
||||
} |
||||
|
||||
public boolean equals(Object o) { |
||||
if (o == this) { |
||||
return true; |
||||
} else if (!(o instanceof List)) { |
||||
return false; |
||||
} else { |
||||
Iterator i1 = iterator(); |
||||
Iterator i2 = ((List)o).iterator(); |
||||
while (i1.hasNext()) { |
||||
if (!i2.hasNext()) { |
||||
return false; |
||||
} else { |
||||
Object e = i1.next(); |
||||
if (e == null ? i2.next() != null : !e.equals(i2.next())) { |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
if (i2.hasNext()) { |
||||
return false; |
||||
} else { |
||||
return true; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public int hashCode() { |
||||
int hashCode = 1; |
||||
Iterator i = iterator(); |
||||
while (i.hasNext()) { |
||||
Object obj = i.next(); |
||||
hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode()); |
||||
} |
||||
return hashCode; |
||||
} |
||||
|
||||
public int indexOf(Object o) { |
||||
int index = 0; |
||||
ListIterator i = listIterator(); |
||||
if (o == null) { |
||||
while (i.hasNext()) { |
||||
if (i.next() == null) { |
||||
return index; |
||||
} |
||||
index++; |
||||
} |
||||
} else { |
||||
while (i.hasNext()) { |
||||
if (o.equals(i.next())) { |
||||
return index; |
||||
} |
||||
index++; |
||||
} |
||||
} |
||||
return -1; |
||||
} |
||||
|
||||
public Iterator iterator() { |
||||
return new Iterator() { |
||||
private int knownMod = modCount; |
||||
private int position = 0; |
||||
boolean removed = true; |
||||
|
||||
private void checkMod() { |
||||
if (knownMod != modCount) { |
||||
throw new ConcurrentModificationException(); |
||||
} |
||||
} |
||||
|
||||
public boolean hasNext() { |
||||
checkMod(); |
||||
return position < size(); |
||||
} |
||||
|
||||
public Object next() { |
||||
checkMod(); |
||||
removed = false; |
||||
try { |
||||
return get(position++); |
||||
} catch (IndexOutOfBoundsException e) { |
||||
throw new NoSuchElementException(); |
||||
} |
||||
} |
||||
|
||||
public void remove() { |
||||
checkMod(); |
||||
if (removed) { |
||||
throw new IllegalStateException(); |
||||
} |
||||
AbstractList.this.remove(--position); |
||||
knownMod = modCount; |
||||
removed = true; |
||||
} |
||||
}; |
||||
} |
||||
|
||||
public int lastIndexOf(Object o) { |
||||
int index = size(); |
||||
ListIterator i = listIterator(index); |
||||
if (o == null) { |
||||
while (i.hasPrevious()) { |
||||
if (i.previous() == null) { |
||||
return index; |
||||
} |
||||
index--; |
||||
} |
||||
} else { |
||||
while (i.hasPrevious()) { |
||||
if (o.equals(i.previous())) { |
||||
return index; |
||||
} |
||||
index--; |
||||
} |
||||
} |
||||
return -1; |
||||
} |
||||
|
||||
public ListIterator listIterator() { |
||||
return listIterator(0); |
||||
} |
||||
|
||||
public ListIterator listIterator(final int index) { |
||||
|
||||
if (index < 0 || index > size()) { |
||||
throw new IndexOutOfBoundsException(); |
||||
} |
||||
|
||||
return new ListIterator() { |
||||
private int knownMod = modCount; |
||||
private int position = index; |
||||
private int lastReturned = -1; |
||||
|
||||
private void checkMod() { |
||||
if (knownMod != modCount) { |
||||
throw new ConcurrentModificationException(); |
||||
} |
||||
} |
||||
|
||||
public boolean hasNext() { |
||||
checkMod(); |
||||
return position < size(); |
||||
} |
||||
|
||||
public boolean hasPrevious() { |
||||
checkMod(); |
||||
return position > 0; |
||||
} |
||||
|
||||
public Object next() { |
||||
checkMod(); |
||||
if (hasNext()) { |
||||
lastReturned = position++; |
||||
return get(lastReturned); |
||||
} else { |
||||
throw new NoSuchElementException(); |
||||
} |
||||
} |
||||
|
||||
public Object previous() { |
||||
checkMod(); |
||||
if (hasPrevious()) { |
||||
lastReturned = --position; |
||||
return get(lastReturned); |
||||
} else { |
||||
throw new NoSuchElementException(); |
||||
} |
||||
} |
||||
|
||||
public int nextIndex() { |
||||
checkMod(); |
||||
return position; |
||||
} |
||||
|
||||
public int previousIndex() { |
||||
checkMod(); |
||||
return position - 1; |
||||
} |
||||
|
||||
public void remove() { |
||||
checkMod(); |
||||
if (lastReturned < 0) { |
||||
throw new IllegalStateException(); |
||||
} |
||||
AbstractList.this.remove(lastReturned); |
||||
knownMod = modCount; |
||||
position = lastReturned; |
||||
lastReturned = -1; |
||||
} |
||||
|
||||
public void set(Object o) { |
||||
checkMod(); |
||||
if (lastReturned < 0) { |
||||
throw new IllegalStateException(); |
||||
} |
||||
AbstractList.this.set(lastReturned, o); |
||||
} |
||||
|
||||
public void add(Object o) { |
||||
checkMod(); |
||||
AbstractList.this.add(position++, o); |
||||
lastReturned = -1; |
||||
knownMod = modCount; |
||||
} |
||||
}; |
||||
} |
||||
|
||||
public Object remove(int index) { |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
/** |
||||
* Remove a subsection of the list. This is called by the clear and |
||||
* removeRange methods of the class which implements subList, which are |
||||
* difficult for subclasses to override directly. Therefore, this method |
||||
* should be overridden instead by the more efficient implementation, if one |
||||
* exists. |
||||
* <p> |
||||
* This implementation first checks for illegal or out of range arguments. It |
||||
* then obtains a ListIterator over the list using listIterator(fromIndex). |
||||
* It then calls next() and remove() on this iterator repeatedly, toIndex - |
||||
* fromIndex times. |
||||
* |
||||
* @param fromIndex the index, inclusive, to remove from. |
||||
* @param toIndex the index, exclusive, to remove to. |
||||
* @exception UnsupportedOperationException if this list does not support |
||||
* the removeRange operation. |
||||
* @exception IndexOutOfBoundsException if fromIndex > toIndex || fromIndex < |
||||
* 0 || toIndex > size(). |
||||
*/ |
||||
protected void removeRange(int fromIndex, int toIndex) { |
||||
if (fromIndex > toIndex) { |
||||
throw new IllegalArgumentException(); |
||||
} else if (fromIndex < 0 || toIndex > size()) { |
||||
throw new IndexOutOfBoundsException(); |
||||
} else { |
||||
ListIterator i = listIterator(fromIndex); |
||||
for (int index = fromIndex; index < toIndex; index++) { |
||||
i.next(); |
||||
i.remove(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public Object set(int index, Object o) { |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
private static class SubList extends AbstractList { |
||||
|
||||
// Note that within this class two fields called modCount are inherited -
|
||||
// one from the superclass, and one from the backing class. These are
|
||||
// explicitly disambiguated in the code by referring to "this.modCount"
|
||||
// and "backing.modCount".
|
||||
// The code uses both these two fields and *no other* to provide fail-fast
|
||||
// behaviour. For correct operation, the two fields should contain equal
|
||||
// values. Therefore, if this.modCount != backing.modCount, there
|
||||
// has been a concurrent modification. This is all achieved purely by using
|
||||
// the modCount field, precisely according to the docs of AbstractList.
|
||||
// See the methods upMod and checkMod.
|
||||
|
||||
// Jikes doesn't want to access outer instance with AbstractList.this,
|
||||
// since this is an AbstractList, too. I therefor changed class to static
|
||||
// and do it by hand. This makes it a lot clearer by the way.
|
||||
private AbstractList backing; |
||||
private final int offset; |
||||
private int size; |
||||
|
||||
SubList(AbstractList backing, int fromIndex, int toIndex) { |
||||
this.backing = backing; |
||||
this.offset = fromIndex; |
||||
this.size = toIndex - fromIndex; |
||||
|
||||
upMod(); |
||||
} |
||||
|
||||
/** |
||||
* This method checks the two modCount fields to ensure that there has |
||||
* not been a concurrent modification. It throws an exception if there |
||||
* has been, and otherwise returns normally. |
||||
* Note that since this method is private, it will be inlined. |
||||
* |
||||
* @exception ConcurrentModificationException if there has been a |
||||
* concurrent modification. |
||||
*/ |
||||
private void checkMod() { |
||||
if (modCount != backing.modCount) { |
||||
throw new ConcurrentModificationException(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* This method is called after every method that causes a structural |
||||
* modification to the backing list. It updates the local modCount field |
||||
* to match that of the backing list. |
||||
* Note that since this method is private, it will be inlined. |
||||
*/ |
||||
private void upMod() { |
||||
modCount = backing.modCount; |
||||
} |
||||
|
||||
/** |
||||
* This method checks that a value is between 0 and size (inclusive). If |
||||
* it is not, an exception is thrown. |
||||
* Note that since this method is private, it will be inlined. |
||||
* |
||||
* @exception IndexOutOfBoundsException if the value is out of range. |
||||
*/ |
||||
private void checkBoundsInclusive(int index) { |
||||
if (index < 0 || index > size) { |
||||
throw new IndexOutOfBoundsException(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* This method checks that a value is between 0 (inclusive) and size |
||||
* (exclusive). If it is not, an exception is thrown. |
||||
* Note that since this method is private, it will be inlined. |
||||
* |
||||
* @exception IndexOutOfBoundsException if the value is out of range. |
||||
*/ |
||||
private void checkBoundsExclusive(int index) { |
||||
if (index < 0 || index >= size) { |
||||
throw new IndexOutOfBoundsException(); |
||||
} |
||||
} |
||||
|
||||
public int size() { |
||||
checkMod(); |
||||
return size; |
||||
} |
||||
|
||||
public Iterator iterator() { |
||||
return listIterator(); |
||||
} |
||||
|
||||
public ListIterator listIterator(final int index) { |
||||
|
||||
checkMod(); |
||||
checkBoundsInclusive(index); |
||||
|
||||
return new ListIterator() { |
||||
ListIterator i = backing.listIterator(index + offset); |
||||
int position = index; |
||||
|
||||
public boolean hasNext() { |
||||
checkMod(); |
||||
return position < size; |
||||
} |
||||
|
||||
public boolean hasPrevious() { |
||||
checkMod(); |
||||
return position > 0; |
||||
} |
||||
|
||||
public Object next() { |
||||
if (position < size) { |
||||
Object o = i.next(); |
||||
position++; |
||||
return o; |
||||
} else { |
||||
throw new NoSuchElementException(); |
||||
} |
||||
} |
||||
|
||||
public Object previous() { |
||||
if (position > 0) { |
||||
Object o = i.previous(); |
||||
position--; |
||||
return o; |
||||
} else { |
||||
throw new NoSuchElementException(); |
||||
} |
||||
} |
||||
|
||||
public int nextIndex() { |
||||
return offset + i.nextIndex(); |
||||
} |
||||
|
||||
public int previousIndex() { |
||||
return offset + i.previousIndex(); |
||||
} |
||||
|
||||
public void remove() { |
||||
i.remove(); |
||||
upMod(); |
||||
size--; |
||||
position = nextIndex(); |
||||
} |
||||
|
||||
public void set(Object o) { |
||||
i.set(o); |
||||
} |
||||
|
||||
public void add(Object o) { |
||||
i.add(o); |
||||
upMod(); |
||||
size++; |
||||
position++; |
||||
} |
||||
|
||||
// Here is the reason why the various modCount fields are mostly
|
||||
// ignored in this wrapper listIterator.
|
||||
// IF the backing listIterator is failfast, then the following holds:
|
||||
// Using any other method on this list will call a corresponding
|
||||
// method on the backing list *after* the backing listIterator
|
||||
// is created, which will in turn cause a ConcurrentModException
|
||||
// when this listIterator comes to use the backing one. So it is
|
||||
// implicitly failfast.
|
||||
// If the backing listIterator is NOT failfast, then the whole of
|
||||
// this list isn't failfast, because the modCount field of the
|
||||
// backing list is not valid. It would still be *possible* to
|
||||
// make the iterator failfast wrt modifications of the sublist
|
||||
// only, but somewhat pointless when the list can be changed under
|
||||
// us.
|
||||
// Either way, no explicit handling of modCount is needed.
|
||||
// However upMod() must be called in add and remove, and size
|
||||
// must also be updated in these two methods, since they do not go
|
||||
// through the corresponding methods of the subList.
|
||||
|
||||
}; |
||||
} |
||||
|
||||
public Object set(int index, Object o) { |
||||
checkMod(); |
||||
checkBoundsExclusive(index); |
||||
o = backing.set(index + offset, o); |
||||
upMod(); |
||||
return o; |
||||
} |
||||
|
||||
public Object get(int index) { |
||||
checkMod(); |
||||
checkBoundsExclusive(index); |
||||
return backing.get(index + offset); |
||||
} |
||||
|
||||
public void add(int index, Object o) { |
||||
checkMod(); |
||||
checkBoundsInclusive(index); |
||||
backing.add(index + offset, o); |
||||
upMod(); |
||||
size++; |
||||
} |
||||
|
||||
public Object remove(int index) { |
||||
checkMod(); |
||||
checkBoundsExclusive(index); |
||||
Object o = backing.remove(index + offset); |
||||
upMod(); |
||||
size--; |
||||
return o; |
||||
} |
||||
|
||||
public void removeRange(int fromIndex2, int toIndex2) { |
||||
checkMod(); |
||||
checkBoundsExclusive(fromIndex2); |
||||
checkBoundsInclusive(toIndex2); |
||||
|
||||
// this call will catch the toIndex2 < fromIndex2 condition
|
||||
backing.removeRange(offset + fromIndex2, offset + toIndex2); |
||||
upMod(); |
||||
size -= toIndex2 - fromIndex2; |
||||
} |
||||
|
||||
public boolean addAll(int index, Collection c) { |
||||
checkMod(); |
||||
checkBoundsInclusive(index); |
||||
int s = backing.size(); |
||||
boolean result = backing.addAll(offset + index, c); |
||||
upMod(); |
||||
size += backing.size() - s; |
||||
return result; |
||||
} |
||||
} |
||||
|
||||
public List subList(final int fromIndex, final int toIndex) { |
||||
return new SubList(this, fromIndex, toIndex); |
||||
} |
||||
|
||||
} |
@ -1,280 +0,0 @@ |
||||
// This interface is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AbstractMap.java -- Abstract implementation of most of Map
|
||||
//
|
||||
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com),
|
||||
// Free Software Foundation, Inc.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TO DO:
|
||||
// comments
|
||||
// test suite
|
||||
|
||||
package jode.util; |
||||
|
||||
public abstract class AbstractMap implements Map { |
||||
|
||||
public void clear() |
||||
{ |
||||
entrySet().clear(); |
||||
} |
||||
|
||||
public boolean containsKey( Object key ) |
||||
{ |
||||
Object k; |
||||
Iterator entries = entrySet().iterator(); |
||||
|
||||
while( entries.hasNext() ) |
||||
{ |
||||
k = ((Map.Entry)entries.next()).getKey(); |
||||
if( key == null ? k == null : key.equals( k ) ) |
||||
return true; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
public boolean containsValue( Object value ) |
||||
{ |
||||
Object v; |
||||
Iterator entries = entrySet().iterator(); |
||||
|
||||
while( entries.hasNext() ) |
||||
{ |
||||
v = ((Map.Entry)entries.next()).getValue(); |
||||
if( value == null ? v == null : value.equals( v ) ) |
||||
return true; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
public abstract Set entrySet(); |
||||
|
||||
public boolean equals( Object o ) |
||||
{ |
||||
if( this == o ) |
||||
return true; |
||||
|
||||
if( o == null || !( o instanceof Map ) ) |
||||
return false; |
||||
|
||||
Map m = (Map)o; |
||||
if( m.size() != size() ) |
||||
return false; |
||||
|
||||
Object key, value1, value2; |
||||
Map.Entry entry; |
||||
Iterator entries = entrySet().iterator(); |
||||
while( entries.hasNext() ) |
||||
{ |
||||
entry = (Map.Entry)entries.next(); |
||||
key = entry.getKey(); |
||||
value1 = entry.getValue(); |
||||
value2 = m.get( key ); |
||||
|
||||
if( !( ( value1 == null && value2 == null ) |
||||
|| value1.equals( value2 ) ) ) |
||||
return false; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
public Object get( Object key ) |
||||
{ |
||||
Object k; |
||||
Map.Entry entry; |
||||
Iterator entries = entrySet().iterator(); |
||||
|
||||
while( entries.hasNext() ) |
||||
{ |
||||
entry = (Map.Entry)entries.next(); |
||||
k = entry.getKey(); |
||||
if( key == null ? k == null : key.equals( k ) ) |
||||
return entry.getValue(); |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
public int hashCode() |
||||
{ |
||||
int hashcode = 0; |
||||
Iterator entries = entrySet().iterator(); |
||||
|
||||
while( entries.hasNext() ) |
||||
hashcode += entries.next().hashCode(); |
||||
|
||||
return hashcode; |
||||
} |
||||
|
||||
public boolean isEmpty() |
||||
{ |
||||
return size() == 0; |
||||
} |
||||
|
||||
public Set keySet() |
||||
{ |
||||
if( this.keySet == null ) |
||||
{ |
||||
this.keySet = |
||||
new AbstractSet() |
||||
{ |
||||
public int size() |
||||
{ |
||||
return AbstractMap.this.size(); |
||||
} |
||||
|
||||
public boolean contains(Object key) |
||||
{ |
||||
return AbstractMap.this.containsKey(key); |
||||
} |
||||
|
||||
public Iterator iterator() |
||||
{ |
||||
return new Iterator() |
||||
{ |
||||
Iterator map_iterator = AbstractMap.this.entrySet().iterator(); |
||||
|
||||
public boolean hasNext() |
||||
{ |
||||
return map_iterator.hasNext(); |
||||
} |
||||
|
||||
public Object next() |
||||
{ |
||||
return ((Map.Entry)map_iterator.next()).getKey(); |
||||
} |
||||
|
||||
public void remove() |
||||
{ |
||||
map_iterator.remove(); |
||||
} |
||||
}; |
||||
} |
||||
}; |
||||
} |
||||
|
||||
return this.keySet; |
||||
} |
||||
|
||||
public Object put( Object key, Object value ) |
||||
{ |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
public void putAll( Map m ) |
||||
{ |
||||
Map.Entry entry; |
||||
Iterator entries = m.entrySet().iterator(); |
||||
while( entries.hasNext() ) |
||||
{ |
||||
entry = (Map.Entry)entries.next(); |
||||
put( entry.getKey(), entry.getValue() ); |
||||
} |
||||
} |
||||
|
||||
public Object remove( Object key ) |
||||
{ |
||||
Object k, value; |
||||
Map.Entry entry; |
||||
Iterator entries = entrySet().iterator(); |
||||
|
||||
while( entries.hasNext() ) |
||||
{ |
||||
entry = (Map.Entry)entries.next(); |
||||
k = entry.getKey(); |
||||
if( key == null ? k == null : key.equals( k ) ) |
||||
{ |
||||
value = entry.getValue(); |
||||
entries.remove(); |
||||
return value; |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
public int size() |
||||
{ |
||||
return entrySet().size(); |
||||
} |
||||
|
||||
public String toString() |
||||
{ |
||||
Map.Entry entry; |
||||
String rep = "AbstractMap< "; |
||||
Iterator entries = entrySet().iterator(); |
||||
|
||||
while( entries.hasNext() ) |
||||
{ |
||||
entry = (Map.Entry)entries.next(); |
||||
rep += entry.getKey() + " -> " + entry.getValue() + ", "; |
||||
} |
||||
|
||||
return rep.substring( 0, rep.length() - 2 ) + " >"; |
||||
} |
||||
|
||||
public Collection values() |
||||
{ |
||||
if( this.valueCollection == null ) |
||||
{ |
||||
this.valueCollection = |
||||
new AbstractCollection() |
||||
{ |
||||
public int size() |
||||
{ |
||||
return AbstractMap.this.size(); |
||||
} |
||||
|
||||
public Iterator iterator() |
||||
{ |
||||
return new Iterator() |
||||
{ |
||||
Iterator map_iterator = AbstractMap.this.entrySet().iterator(); |
||||
|
||||
public boolean hasNext() |
||||
{ |
||||
return map_iterator.hasNext(); |
||||
} |
||||
|
||||
public Object next() |
||||
{ |
||||
return ((Map.Entry)map_iterator.next()).getValue(); |
||||
} |
||||
|
||||
public void remove() |
||||
{ |
||||
map_iterator.remove(); |
||||
} |
||||
}; |
||||
} |
||||
}; |
||||
} |
||||
|
||||
return this.valueCollection; |
||||
} |
||||
|
||||
|
||||
private Collection valueCollection = null; |
||||
private Set keySet = null; |
||||
} |
@ -1,111 +0,0 @@ |
||||
// This interface is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AbstractSequentialList.java -- List implementation for sequential access
|
||||
//
|
||||
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TO DO:
|
||||
// ~ Lots of doc comments still missing.
|
||||
// ~ The class comment should include a description of what should be overridden
|
||||
// to provide what features, as should the listIterator comment.
|
||||
|
||||
package jode.util; |
||||
|
||||
/** |
||||
* Abstract superclass to make it easier to implement the List interface when |
||||
* backed by a sequential-access store, such as a linked list. |
||||
*/ |
||||
public abstract class AbstractSequentialList extends AbstractList { |
||||
|
||||
/** |
||||
* Returns a ListIterator over the list, starting from position index. |
||||
* Subclasses must provide an implementation of this method. |
||||
* |
||||
* @exception IndexOutOfBoundsException if index < 0 || index > size() |
||||
*/ |
||||
public abstract ListIterator listIterator(int index); |
||||
|
||||
/** |
||||
* Add an element to the list at a given index. This implementation obtains a |
||||
* ListIterator positioned at the specified index, and then adds the element |
||||
* using the ListIterator's add method. |
||||
* |
||||
* @param index the position to add the element |
||||
* @param o the element to insert |
||||
* @exception IndexOutOfBoundsException if index < 0 || index > size() |
||||
* @exception UnsupportedOperationException if the iterator returned by |
||||
* listIterator(index) does not support the add method. |
||||
*/ |
||||
public void add(int index, Object o) { |
||||
ListIterator i = listIterator(index); |
||||
i.add(o); |
||||
} |
||||
|
||||
public boolean addAll(int index, Collection c) { |
||||
boolean changed = false; |
||||
Iterator ci = c.iterator(); |
||||
ListIterator i = listIterator(index); |
||||
while (ci.hasNext()) { |
||||
i.add(ci.next()); |
||||
changed = true; |
||||
} |
||||
return changed; |
||||
} |
||||
|
||||
public Object get(int index) { |
||||
ListIterator i = listIterator(index); |
||||
if (!i.hasNext()) { |
||||
throw new IndexOutOfBoundsException(); |
||||
} |
||||
return i.next(); |
||||
} |
||||
|
||||
/** |
||||
* Return an Iterator over this List. This implementation returns |
||||
* listIterator(). |
||||
* |
||||
* @return an Iterator over this List |
||||
*/ |
||||
public Iterator iterator() { |
||||
return listIterator(); |
||||
} |
||||
|
||||
public Object remove(int index) { |
||||
ListIterator i = listIterator(index); |
||||
if (!i.hasNext()) { |
||||
throw new IndexOutOfBoundsException(); |
||||
} |
||||
Object removed = i.next(); |
||||
i.remove(); |
||||
return removed; |
||||
} |
||||
|
||||
public Object set(int index, Object o) { |
||||
ListIterator i = listIterator(index); |
||||
if (!i.hasNext()) { |
||||
throw new IndexOutOfBoundsException(); |
||||
} |
||||
Object old = i.next(); |
||||
i.set(o); |
||||
return old; |
||||
} |
||||
} |
@ -1,78 +0,0 @@ |
||||
// This interface is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AbstractSet.java -- Abstract implementation of most of Set
|
||||
//
|
||||
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package jode.util; |
||||
|
||||
/** |
||||
* An abstract implementation of Set to make it easier to create your own |
||||
* implementations. In order to create a Set, subclass AbstractSet and |
||||
* implement the same methods that are required for AbstractCollection |
||||
* (although these methods must of course meet the requirements that Set puts |
||||
* on them - specifically, no element may be in the set more than once). This |
||||
* class simply provides implementations of equals() and hashCode() to fulfil |
||||
* the requirements placed on them by the Set interface. |
||||
*/ |
||||
public abstract class AbstractSet extends AbstractCollection implements Set { |
||||
|
||||
/** |
||||
* Tests whether the given object is equal to this Set. This implementation |
||||
* first checks whether this set <em>is</em> the given object, and returns |
||||
* true if so. Otherwise, if o is a Set and is the same size as this one, it |
||||
* returns the result of calling containsAll on the given Set. Otherwise, it |
||||
* returns false. |
||||
* |
||||
* @param o the Object to be tested for equality with this Set |
||||
* @return true if the given object is equal to this Set |
||||
*/ |
||||
public boolean equals(Object o) { |
||||
if (o == this) { |
||||
return true; |
||||
} else if (o instanceof Set && ((Set)o).size() == size()) { |
||||
return containsAll((Collection)o); |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Returns a hash code for this Set. The hash code of a Set is the sum of the |
||||
* hash codes of all its elements, except that the hash code of null is |
||||
* defined to be zero. This implementation obtains an Iterator over the Set, |
||||
* and sums the results. |
||||
* |
||||
* @return a hash code for this Set |
||||
*/ |
||||
public int hashCode() { |
||||
int hash = 0; |
||||
Iterator i = iterator(); |
||||
while (i.hasNext()) { |
||||
try { |
||||
hash += i.next().hashCode(); |
||||
} catch (NullPointerException e) { |
||||
} |
||||
} |
||||
return hash; |
||||
} |
||||
} |
@ -1,489 +0,0 @@ |
||||
// This class is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// ArrayList.java -- JDK1.2's answer to Vector; this is an array-backed
|
||||
// implementation of the List interface
|
||||
//
|
||||
// This is a JDK 1.2 compliant version of ArrayList.java
|
||||
//
|
||||
// Copyright (c) 1998 by Jon A. Zeppieri (jon@eease.com),
|
||||
// Free Software Foundation, Inc.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
package jode.util; |
||||
|
||||
import java.lang.reflect.Array; |
||||
import java.io.Serializable; |
||||
import java.io.IOException; |
||||
import java.io.ObjectInputStream; |
||||
import java.io.ObjectOutputStream; |
||||
|
||||
/** |
||||
* An array-backed implementation of the List interface. ArrayList |
||||
* performs well on simple tasks: random access into a list, appending |
||||
* to or removing from the end of a list, checking the size, &c. |
||||
* |
||||
* @author Jon A. Zeppieri |
||||
* @version $Id$ |
||||
* @see java.util.AbstractList |
||||
* @see java.util.List |
||||
*/ |
||||
public class ArrayList extends AbstractList |
||||
implements List, Cloneable, Serializable |
||||
{ |
||||
/** the default capacity for new ArrayLists */ |
||||
private static final int DEFAULT_CAPACITY = 16; |
||||
|
||||
/** the number of elements in this list */ |
||||
int size; |
||||
|
||||
/** where the data is stored */ |
||||
transient Object[] _arData; |
||||
|
||||
/** |
||||
* Construct a new ArrayList with the supplied initial capacity. |
||||
* |
||||
* @param iCapacity |
||||
*/ |
||||
public ArrayList(int iCapacity) |
||||
{ |
||||
_arData = new Object[iCapacity]; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Construct a new ArrayList with the default capcity |
||||
*/ |
||||
public ArrayList() |
||||
{ |
||||
this(DEFAULT_CAPACITY); |
||||
} |
||||
|
||||
/** |
||||
* Construct a new ArrayList, and initialize it with the elements |
||||
* in the supplied Collection; Sun specs say that the initial |
||||
* capacity is 110% of the Collection's size. |
||||
* |
||||
* @param oCollection the collection whose elements will |
||||
* initialize this list |
||||
*/ |
||||
public ArrayList(Collection oCollection) |
||||
{ |
||||
this((int) (oCollection.size() * 1.1)); |
||||
addAll(oCollection); |
||||
} |
||||
|
||||
/** |
||||
* Guarantees that this list will have at least enough capacity to |
||||
* hold iMinCapacity elements. |
||||
* |
||||
* @param iMinCapacity the minimum guaranteed capacity |
||||
*/ |
||||
public void ensureCapacity(int iMinCapacity) |
||||
{ |
||||
Object[] arNewData; |
||||
int iCapacity = _arData.length; |
||||
|
||||
if (iMinCapacity > iCapacity) |
||||
{ |
||||
arNewData = new Object[Math.max((iCapacity * 2), iMinCapacity)]; |
||||
System.arraycopy(_arData, 0, arNewData, 0, iCapacity); |
||||
_arData = arNewData; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Appends the supplied element to the end of this list. |
||||
* |
||||
* @param oElement the element to be appended to this list |
||||
*/ |
||||
public boolean add(Object oElement) |
||||
{ |
||||
ensureCapacity(size + 1); |
||||
_arData[size++] = oElement; |
||||
modCount++; |
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* Retrieves the element at the user-supplied index. |
||||
* |
||||
* @param iIndex the index of the element we are fetching |
||||
* @throws IndexOutOfBoundsException (iIndex < 0) || (iIndex >= size()) |
||||
*/ |
||||
public Object get(int iIndex) |
||||
{ |
||||
if (iIndex >= size) |
||||
throw new IndexOutOfBoundsException("ArrayList size=" + |
||||
String.valueOf(size) + "; " + |
||||
"index=" + String.valueOf(iIndex)); |
||||
return _arData[iIndex]; |
||||
} |
||||
|
||||
/** |
||||
* Returns the number of elements in this list |
||||
*/ |
||||
public int size() |
||||
{ |
||||
return size; |
||||
} |
||||
|
||||
/** |
||||
* Removes the element at the user-supplied index |
||||
* |
||||
* @param iIndex the index of the element to be removed |
||||
* @return the removed Object |
||||
* @throws IndexOutOfBoundsException (iIndex < 0) || (iIndex >= size()) |
||||
*/ |
||||
public Object remove(int iIndex) |
||||
{ |
||||
Object oResult; |
||||
|
||||
if (iIndex >= size) |
||||
throw new IndexOutOfBoundsException("ArrayList size=" + |
||||
String.valueOf(size) + "; " + |
||||
"index=" + String.valueOf(iIndex)); |
||||
|
||||
oResult = _arData[iIndex]; |
||||
|
||||
if (iIndex != --size) |
||||
System.arraycopy(_arData, (iIndex + 1), _arData, iIndex, |
||||
(size - iIndex)); |
||||
|
||||
modCount++; |
||||
_arData[size] = null; |
||||
|
||||
return oResult; |
||||
} |
||||
|
||||
/** |
||||
* Removes all elements in the half-open interval [iFromIndex, iToIndex). |
||||
* |
||||
* @param iFromIndex the first index which will be removed |
||||
* @param iToIndex one greater than the last index which will be |
||||
* removed |
||||
*/ |
||||
public void removeRange(int iFromIndex, int iToIndex) |
||||
{ |
||||
int iReduction; |
||||
int i; |
||||
|
||||
if ((iFromIndex >= size) || (iToIndex >= size)) |
||||
{ |
||||
throw new IndexOutOfBoundsException("ArrayList size=" + |
||||
String.valueOf(size) + "; " + |
||||
"indices=" + |
||||
String.valueOf(iFromIndex) + "," + |
||||
String.valueOf(iToIndex)); |
||||
} |
||||
else if (iFromIndex > iToIndex) |
||||
{ |
||||
throw new IllegalArgumentException("fromIndex(" + |
||||
String.valueOf(iFromIndex) + |
||||
") > toIndex(" + |
||||
String.valueOf(iToIndex) + ")"); |
||||
} |
||||
else if (iFromIndex != iToIndex) |
||||
{ |
||||
iReduction = iToIndex - iFromIndex; |
||||
System.arraycopy(_arData, (iFromIndex + iReduction), _arData, |
||||
iFromIndex, (size - iFromIndex - iReduction)); |
||||
modCount++; |
||||
|
||||
for (i = (iFromIndex + iReduction); i < size; i++) |
||||
_arData[i] = null; |
||||
|
||||
size -= iReduction; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Adds the supplied element at the specified index, shifting all |
||||
* elements currently at that index or higher one to the right. |
||||
* |
||||
* @param iIndex the index at which the element is being added |
||||
* @param oElement the element being added |
||||
*/ |
||||
public void add(int iIndex, Object oElement) |
||||
{ |
||||
if (iIndex > size) |
||||
throw new IndexOutOfBoundsException("ArrayList size=" + |
||||
String.valueOf(size) + "; " + |
||||
"index=" + String.valueOf(iIndex)); |
||||
|
||||
ensureCapacity(size + 1); |
||||
System.arraycopy(_arData, iIndex, _arData, |
||||
(iIndex + 1), (size - iIndex)); |
||||
_arData[iIndex] = oElement; |
||||
size++; |
||||
modCount++; |
||||
} |
||||
|
||||
/** |
||||
* Add each element in the supplied Collection to this List. |
||||
* |
||||
* @param oCollection a Collection containing elements to be |
||||
* added to this List |
||||
*/ |
||||
public boolean addAll(Collection oCollection) |
||||
{ |
||||
Iterator itElements; |
||||
int iLen = oCollection.size(); |
||||
|
||||
if (iLen > 0) |
||||
{ |
||||
ensureCapacity(size + iLen); |
||||
modCount++; |
||||
|
||||
itElements = oCollection.iterator(); |
||||
|
||||
while (itElements.hasNext()) |
||||
_arData[size++] = itElements.next(); |
||||
|
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Add all elements in the supplied collection, inserting them beginning |
||||
* at the specified index. |
||||
* |
||||
* @param iIndex the index at which the elements will be inserted |
||||
* @param oCollection the Collection containing the elements to be |
||||
* inserted |
||||
*/ |
||||
public boolean addAll(int iIndex, Collection oCollection) |
||||
{ |
||||
Iterator itElements; |
||||
int iLen; |
||||
|
||||
if (iIndex > size) |
||||
throw new IndexOutOfBoundsException("ArrayList size=" + |
||||
String.valueOf(size) + "; " + |
||||
"index=" + String.valueOf(iIndex)); |
||||
|
||||
iLen = oCollection.size(); |
||||
|
||||
if (iLen > 0) |
||||
{ |
||||
ensureCapacity(size + iLen); |
||||
|
||||
System.arraycopy(_arData, iIndex, _arData, |
||||
(iIndex + iLen), (size - iIndex)); |
||||
modCount++; |
||||
size += iLen; |
||||
|
||||
itElements = oCollection.iterator(); |
||||
while (itElements.hasNext()) |
||||
_arData[iIndex++] = itElements.next(); |
||||
|
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Creates a shallow copy of this ArrayList |
||||
*/ |
||||
public Object clone() |
||||
{ |
||||
ArrayList oClone; |
||||
|
||||
try |
||||
{ |
||||
oClone = (ArrayList) super.clone(); |
||||
oClone._arData = _arData; |
||||
oClone.size = size; |
||||
} |
||||
catch(CloneNotSupportedException e) |
||||
{ |
||||
oClone = null; |
||||
} |
||||
return oClone; |
||||
} |
||||
|
||||
/** |
||||
* Returns true iff oElement is in this ArrayList. |
||||
* |
||||
* @param oElement the element whose inclusion in the List is being |
||||
* tested |
||||
*/ |
||||
public boolean contains(Object oElement) |
||||
{ |
||||
return (indexOf(oElement) != -1); |
||||
} |
||||
|
||||
/** |
||||
* Returns the lowest index at which oElement appears in this List, or |
||||
* -1 if it does not appear. |
||||
* |
||||
* @param oElement the element whose inclusion in the List is being |
||||
* tested |
||||
*/ |
||||
public int indexOf(Object oElement) |
||||
{ |
||||
int i; |
||||
|
||||
for (i = 0; i < size; i++) |
||||
{ |
||||
if (doesEqual(oElement, _arData[i])) |
||||
return i; |
||||
} |
||||
return -1; |
||||
} |
||||
|
||||
/** |
||||
* Returns the highest index at which oElement appears in this List, or |
||||
* -1 if it does not appear. |
||||
* |
||||
* @param oElement the element whose inclusion in the List is being |
||||
* tested |
||||
*/ |
||||
public int lastIndexOf(Object oElement) |
||||
{ |
||||
int i; |
||||
|
||||
for (i = size - 1; i >= 0; i--) |
||||
{ |
||||
if (doesEqual(oElement, _arData[i])) |
||||
return i; |
||||
} |
||||
return -1; |
||||
} |
||||
|
||||
/** |
||||
* Removes all elements from this List |
||||
*/ |
||||
public void clear() |
||||
{ |
||||
int i; |
||||
|
||||
if (size > 0) |
||||
{ |
||||
modCount++; |
||||
size = 0; |
||||
|
||||
for (i = 0; i < size; i++) |
||||
_arData[i] = null; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Sets the element at the specified index. |
||||
* |
||||
* @param iIndex the index at which the element is being set |
||||
* @param oElement the element to be set |
||||
* @return the element previously at the specified index, or null if |
||||
* none was there |
||||
*/ |
||||
public Object set(int iIndex, Object oElement) |
||||
{ |
||||
Object oResult; |
||||
|
||||
if (iIndex >= size) |
||||
throw new IndexOutOfBoundsException("ArrayList size=" + |
||||
String.valueOf(size) + "; " + |
||||
"index=" + String.valueOf(iIndex)); |
||||
oResult = _arData[iIndex]; |
||||
modCount++; |
||||
_arData[iIndex] = oElement; |
||||
|
||||
return oResult; |
||||
} |
||||
|
||||
/** |
||||
* Returns an Object Array containing all of the elements in this ArrayList |
||||
*/ |
||||
public Object[] toArray() |
||||
{ |
||||
Object[] arObjects = new Object[size]; |
||||
System.arraycopy(_arData, 0, arObjects, 0, size); |
||||
return arObjects; |
||||
} |
||||
|
||||
/** |
||||
* Returns an Array whse component type is the runtime component type of |
||||
* the passes-in Array. The returned Array is populated with all of the |
||||
* elements in this ArrayList. If the passed-in Array is not large enough |
||||
* to store all of the elements in this List, a new Array will be created |
||||
* and returned; if the passed-in Array is <i>larger</i> than the size |
||||
* of this List, then size() + 1 index will be set to null. |
||||
* |
||||
* @param arObjects the passed-in Array |
||||
*/ |
||||
public Object[] toArray(Object[] arObjects) |
||||
{ |
||||
Object[] arReturn = (arObjects.length >= size) |
||||
? arObjects |
||||
: (Object[]) |
||||
Array.newInstance(arObjects.getClass().getComponentType(), size); |
||||
|
||||
System.arraycopy(_arData, 0, arReturn, 0, size); |
||||
|
||||
if (arReturn.length > size) |
||||
arReturn[size] = null; |
||||
|
||||
return arReturn; |
||||
} |
||||
|
||||
/** |
||||
* Trims the capacity of tjis List to be equal to its size; |
||||
* a memory saver. |
||||
*/ |
||||
public void trimToSize() |
||||
{ |
||||
Object[] arNewData = new Object[size]; |
||||
System.arraycopy(_arData, 0, arNewData, 0, size); |
||||
modCount++; |
||||
_arData = arNewData; |
||||
} |
||||
|
||||
private void writeObject(ObjectOutputStream oOut) |
||||
throws IOException |
||||
{ |
||||
int i; |
||||
|
||||
oOut.defaultWriteObject(); |
||||
|
||||
oOut.writeInt(_arData.length); |
||||
for (i = 0; i < _arData.length; i++) |
||||
oOut.writeObject(_arData[i]); |
||||
} |
||||
|
||||
private void readObject(ObjectInputStream oIn) |
||||
throws IOException, ClassNotFoundException |
||||
{ |
||||
int i; |
||||
int iCapacity; |
||||
oIn.defaultReadObject(); |
||||
|
||||
iCapacity = oIn.readInt(); |
||||
_arData = new Object[iCapacity]; |
||||
|
||||
for (i = 0; i < iCapacity; i++) |
||||
_arData[i] = oIn.readObject(); |
||||
} |
||||
|
||||
private static final boolean doesEqual(Object oOne, Object oTwo) |
||||
{ |
||||
return ((oOne == null) ? (oTwo == null) : oOne.equals(oTwo)); |
||||
} |
||||
} |
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,138 +0,0 @@ |
||||
// This class is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// BasicMapEntry.java -- a class providing a plain-vanilla implementation of
|
||||
// the Map.Entry interface; could be used anywhere in
|
||||
// java.util
|
||||
//
|
||||
// Copyright (c) 1998 by Jon A. Zeppieri (jon@eease.com)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package jode.util; |
||||
///#ifdef JDK12
|
||||
///import java.lang.UnsupportedOperationException;
|
||||
///import java.util.Map;
|
||||
///#endif
|
||||
|
||||
/** |
||||
* a class which implements Map.Entry |
||||
* |
||||
* @author Jon Zeppieri |
||||
* @version $Revision$ |
||||
* @modified $Id$ |
||||
*/ |
||||
class BasicMapEntry implements Map.Entry |
||||
{ |
||||
/** the key */ |
||||
Object key; |
||||
/** the value */ |
||||
Object value; |
||||
|
||||
/** |
||||
* construct a new BasicMapEntry with the given key and value |
||||
* |
||||
* @param newKey the key of this Entry |
||||
* @param newValue the value of this Entry |
||||
*/ |
||||
BasicMapEntry(Object newKey, Object newValue) |
||||
{ |
||||
key = newKey; |
||||
value = newValue; |
||||
} |
||||
|
||||
/** |
||||
* returns true if <pre>o</pre> is a Map.Entry and |
||||
* <pre> |
||||
* (((o.getKey == null) ? (key == null) : |
||||
* o.getKey().equals(key)) && |
||||
* ((o.getValue() == null) ? (value == null) : |
||||
* o.getValue().equals(value))) |
||||
* </pre> |
||||
* |
||||
* NOTE: the calls to getKey() and getValue() in this implementation |
||||
* are <i>NOT</i> superfluous and should not be removed. They insure |
||||
* that subclasses such as HashMapEntry work correctly |
||||
* |
||||
* @param o the Object being tested for equality |
||||
*/ |
||||
public boolean equals(Object o) |
||||
{ |
||||
Map.Entry tester; |
||||
Object oTestingKey, oTestingValue; |
||||
Object oKey, oValue; |
||||
if (o instanceof Map.Entry) |
||||
{ |
||||
tester = (Map.Entry) o; |
||||
oKey = getKey(); |
||||
oValue = getValue(); |
||||
oTestingKey = tester.getKey(); |
||||
oTestingValue = tester.getValue(); |
||||
return (((oTestingKey == null) ? (oKey == null) : |
||||
oTestingKey.equals(oKey)) && |
||||
((oTestingValue == null) ? (oValue == null) : |
||||
oTestingValue.equals(oValue))); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/** returns the key */ |
||||
public Object getKey() |
||||
{ |
||||
return key; |
||||
} |
||||
|
||||
/** returns the value */ |
||||
public Object getValue() |
||||
{ |
||||
return value; |
||||
} |
||||
|
||||
/** the hashCode() for a Map.Entry is |
||||
* <pre> |
||||
* ((getKey() == null) ? 0 : getKey().hashCode()) ^ |
||||
* ((getValue() == null) ? 0 : getValue().hashCode()); |
||||
* </pre> |
||||
* |
||||
* NOTE: the calls to getKey() and getValue() in this implementation |
||||
* are <i>NOT</i> superfluous and should not be removed. They insure |
||||
* that subclasses such as HashMapEntry work correctly |
||||
*/ |
||||
public int hashCode() |
||||
{ |
||||
Object oKey = getKey(); |
||||
Object oValue = getValue(); |
||||
return ((oKey == null) ? 0 : oKey.hashCode()) ^ |
||||
((oValue == null) ? 0 : oValue.hashCode()); |
||||
} |
||||
|
||||
/** |
||||
* sets the value of this Map.Entry |
||||
* |
||||
* @param newValue the new value of this Map.Entry |
||||
*/ |
||||
public Object setValue(Object newValue) |
||||
throws UnsupportedOperationException, ClassCastException, |
||||
IllegalArgumentException, NullPointerException |
||||
{ |
||||
Object oVal = value; |
||||
value = newValue; |
||||
return oVal; |
||||
} |
||||
} |
@ -1,198 +0,0 @@ |
||||
// This class is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Bucket.java -- a class providing a hash-bucket data structure (a lightweight
|
||||
// linked list)
|
||||
//
|
||||
// Copyright (c) 1998 by Jon A. Zeppieri (jon@eease.com)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package jode.util; |
||||
|
||||
/** |
||||
* a class representing a simple, lightweight linked-list, using Node |
||||
* objects as its linked nodes; this is used by Hashtable and HashMap |
||||
* |
||||
* @author Jon Zeppieri |
||||
* @version $Revision$ |
||||
* @modified $Id$ |
||||
*/ |
||||
class Bucket |
||||
{ |
||||
/** the first node of the lined list, originally null */ |
||||
Node first; |
||||
|
||||
/** trivial constructor for a Bucket */ |
||||
Bucket() |
||||
{ |
||||
} |
||||
|
||||
/** add this key / value pair to the list |
||||
* |
||||
* @param entry a Map.Entry object to be added to this list |
||||
*/ |
||||
Map.Entry add(Node newNode) |
||||
{ |
||||
Object oKey; |
||||
Object oTestKey = newNode.getKey(); |
||||
Node it = first; |
||||
Node prev = null; |
||||
if (it == null) // if the list is empty (the ideal case), we make a new single-node list
|
||||
{ |
||||
first = newNode; |
||||
return null; |
||||
} |
||||
else // otherwise try to find where this key already exists in the list,
|
||||
{// and if it does, replace the value with the new one (and return the old one)
|
||||
while (it != null) |
||||
{ |
||||
oKey = it.getKey(); |
||||
if ((oKey == null) ? (oTestKey == null) : |
||||
oKey.equals(oTestKey)) |
||||
{ |
||||
if (prev != null) |
||||
prev.next = newNode; |
||||
else |
||||
first = newNode; |
||||
newNode.next = it.next; |
||||
return it; |
||||
} |
||||
prev = it; |
||||
it = it.next; |
||||
} |
||||
prev.next = newNode; // otherwise, just stick this at the
|
||||
return null; // end of the list
|
||||
} |
||||
} |
||||
|
||||
/** |
||||
* remove a Map.Entry in this list with the supplied key and return its value, |
||||
* if it exists, else return null |
||||
* |
||||
* @param key the key we are looking for in this list |
||||
*/ |
||||
Object removeByKey(Object key) |
||||
{ |
||||
Object oEntryKey; |
||||
Node prev = null; |
||||
Node it = first; |
||||
while (it != null) |
||||
{ |
||||
oEntryKey = it.getKey(); |
||||
if ((oEntryKey == null) ? (key == null) : oEntryKey.equals(key)) |
||||
{ |
||||
if (prev == null) // we are removing the first element
|
||||
first = it.next; |
||||
else |
||||
prev.next = it.next; |
||||
return it.getValue(); |
||||
} |
||||
else |
||||
{ |
||||
prev = it; |
||||
it = it.next; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* return the value which the supplied key maps to, if it maps to anything in this list, |
||||
* otherwise, return null |
||||
* |
||||
* @param key the key mapping to a value that we are looking for |
||||
*/ |
||||
Object getValueByKey(Object key) |
||||
{ |
||||
Node entry = getEntryByKey(key); |
||||
return (entry == null) ? null : entry.getValue(); |
||||
} |
||||
|
||||
/** |
||||
* return the Map.Entry which the supplied key is a part of, if such a Map.Entry exists, |
||||
* null otherwise |
||||
* |
||||
* this method is important for HashMap, which can hold null values and the null key |
||||
* |
||||
* @param key the key for which we are finding the corresponding Map.Entry |
||||
*/ |
||||
Node getEntryByKey(Object key) |
||||
{ |
||||
Object oEntryKey; |
||||
Node it = first; |
||||
while (it != null) |
||||
{ |
||||
oEntryKey = it.getKey(); |
||||
if ((oEntryKey == null) ? (key == null) : oEntryKey.equals(key)) |
||||
return it; |
||||
it = it.next; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* return true if this list has a Map.Entry whose value equals() the supplied value |
||||
* |
||||
* @param value the value we are looking to match in this list |
||||
*/ |
||||
boolean containsValue(Object value) |
||||
{ |
||||
Object oEntryValue; |
||||
Node it = first; |
||||
while (it != null) |
||||
{ |
||||
oEntryValue = it.getValue(); |
||||
if ((oEntryValue == null) ? (value == null) : oEntryValue.equals(value)) |
||||
return true; |
||||
it = it.next; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
// INNSER CLASSES ----------------------------------------------------------
|
||||
|
||||
/** |
||||
* a class represnting a node in our lightweight linked-list |
||||
* that we use for hash buckets; a Node object contains a Map.Entry as its |
||||
* <pre>value</pre> property and a reference (possibly, even hopefully, null) |
||||
* to another Node as its <pre>next</pre> property. |
||||
* |
||||
* There <i>is</i> a reason for not using a highly generic "LinkedNode" type |
||||
* class: we want to eliminate runtime typechecks. |
||||
* |
||||
* @author Jon Zeppieri |
||||
* @version $Revision$ |
||||
* @modified $Id$ |
||||
*/ |
||||
static class Node extends BasicMapEntry implements Map.Entry |
||||
{ |
||||
/** a reference to the next node in the linked list */ |
||||
Node next; |
||||
|
||||
/** non-trivial contructor -- sets the <pre>value</pre> of the Bucket upon instantiation */ |
||||
Node(Object key, Object value) |
||||
{ |
||||
super(key, value); |
||||
} |
||||
|
||||
|
||||
} |
||||
// EOF ------------------------------------------------------------------------
|
||||
} |
@ -1,234 +0,0 @@ |
||||
// This interface is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Collection.java -- Interface that represents a collection of objects
|
||||
//
|
||||
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TO DO:
|
||||
// ~ Maybe some more @see clauses would be helpful.
|
||||
|
||||
package jode.util; |
||||
|
||||
/** |
||||
* Interface that represents a collection of objects. This interface is the |
||||
* root of the collection hierarchy, and does not provide any guarantees about |
||||
* the order of its elements or whether or not duplicate elements are |
||||
* permitted. |
||||
* <p> |
||||
* All methods of this interface that are defined to modify the collection are |
||||
* defined as <dfn>optional</dfn>. An optional operation may throw an |
||||
* UnsupportedOperationException if the data backing this collection does not |
||||
* support such a modification. This may mean that the data structure is |
||||
* immutable, or that it is read-only but may change ("unmodifiable"), or |
||||
* that it is modifiable but of fixed size (such as an array), or any number |
||||
* of other combinations. |
||||
* <p> |
||||
* A class that wishes to implement this interface should consider subclassing |
||||
* AbstractCollection, which provides basic implementations of most of the |
||||
* methods of this interface. Classes that are prepared to make guarantees |
||||
* about ordering or about absence of duplicate elements should consider |
||||
* implementing List or Set respectively, both of which are subinterfaces of |
||||
* Collection. |
||||
* <p> |
||||
* A general-purpose implementation of the Collection interface should in most |
||||
* cases provide at least two constructors: One which takes no arguments and |
||||
* creates an empty collection, and one which takes a Collection as an argument |
||||
* and returns a collection containing the same elements (that is, creates a |
||||
* copy of the argument using its own implementation). |
||||
* |
||||
* @see java.util.List |
||||
* @see java.util.Set |
||||
* @see java.util.AbstractCollection |
||||
*/ |
||||
public interface Collection { |
||||
|
||||
/** |
||||
* Add an element to this collection. |
||||
* |
||||
* @param o the object to add. |
||||
* @returns true if the collection was modified as a result of this action. |
||||
* @exception UnsupportedOperationException if this collection does not |
||||
* support the add operation. |
||||
* @exception ClassCastException if o cannot be added to this collection due |
||||
* to its type. |
||||
* @exception IllegalArgumentException if o cannot be added to this |
||||
* collection for some other reason. |
||||
*/ |
||||
boolean add(Object o); |
||||
|
||||
/** |
||||
* Add the contents of a given collection to this collection. |
||||
* |
||||
* @param c the collection to add. |
||||
* @returns true if the collection was modified as a result of this action. |
||||
* @exception UnsupportedOperationException if this collection does not |
||||
* support the addAll operation. |
||||
* @exception ClassCastException if some element of c cannot be added to this |
||||
* collection due to its type. |
||||
* @exception IllegalArgumentException if some element of c cannot be added |
||||
* to this collection for some other reason. |
||||
*/ |
||||
boolean addAll(Collection c); |
||||
|
||||
/** |
||||
* Clear the collection, such that a subsequent call to isEmpty() would |
||||
* return true. |
||||
* |
||||
* @exception UnsupportedOperationException if this collection does not |
||||
* support the clear operation. |
||||
*/ |
||||
void clear(); |
||||
|
||||
/** |
||||
* Test whether this collection contains a given object as one of its |
||||
* elements. |
||||
* |
||||
* @param o the element to look for. |
||||
* @returns true if this collection contains at least one element e such that |
||||
* <code>o == null ? e == null : o.equals(e)</code>. |
||||
*/ |
||||
boolean contains(Object o); |
||||
|
||||
/** |
||||
* Test whether this collection contains every element in a given collection. |
||||
* |
||||
* @param c the collection to test for. |
||||
* @returns true if for every element o in c, contains(o) would return true. |
||||
*/ |
||||
boolean containsAll(Collection c); |
||||
|
||||
/** |
||||
* Test whether this collection is equal to some object. The Collection |
||||
* interface does not explicitly require any behaviour from this method, and |
||||
* it may be left to the default implementation provided by Object. The Set |
||||
* and List interfaces do, however, require specific behaviour from this |
||||
* method. |
||||
* <p> |
||||
* If an implementation of Collection, which is not also an implementation of |
||||
* Set or List, should choose to implement this method, it should take care |
||||
* to obey the contract of the equals method of Object. In particular, care |
||||
* should be taken to return false when o is a Set or a List, in order to |
||||
* preserve the symmetry of the relation. |
||||
* |
||||
* @param o the object to compare to this collection. |
||||
* @returns true if the o is equal to this collection. |
||||
*/ |
||||
boolean equals(Object o); |
||||
|
||||
/** |
||||
* Obtain a hash code for this collection. The Collection interface does not |
||||
* explicitly require any behaviour from this method, and it may be left to |
||||
* the default implementation provided by Object. The Set and List interfaces |
||||
* do, however, require specific behaviour from this method. |
||||
* <p> |
||||
* If an implementation of Collection, which is not also an implementation of |
||||
* Set or List, should choose to implement this method, it should take care |
||||
* to obey the contract of the hashCode method of Object. Note that this |
||||
* method renders it impossible to correctly implement both Set and List, as |
||||
* the required implementations are mutually exclusive. |
||||
* |
||||
* @returns a hash code for this collection. |
||||
*/ |
||||
int hashCode(); |
||||
|
||||
/** |
||||
* Test whether this collection is empty, that is, if size() == 0. |
||||
* |
||||
* @returns true if this collection contains no elements. |
||||
*/ |
||||
boolean isEmpty(); |
||||
|
||||
/** |
||||
* Obtain an Iterator over this collection. |
||||
* |
||||
* @returns an Iterator over the elements of this collection, in any order. |
||||
*/ |
||||
Iterator iterator(); |
||||
|
||||
/** |
||||
* Remove a single occurrence of an object from this collection. That is, |
||||
* remove an element e, if one exists, such that <code>o == null ? e == null |
||||
* : o.equals(e)</code>. |
||||
* |
||||
* @param o the object to remove. |
||||
* @returns true if the collection changed as a result of this call, that is, |
||||
* if the collection contained at least one occurrence of o. |
||||
* @exception UnsupportedOperationException if this collection does not |
||||
* support the remove operation. |
||||
*/ |
||||
boolean remove(Object o); |
||||
|
||||
/** |
||||
* Remove all elements of a given collection from this collection. That is, |
||||
* remove every element e such that c.contains(e). |
||||
* |
||||
* @returns true if this collection was modified as a result of this call. |
||||
* @exception UnsupportedOperationException if this collection does not |
||||
* support the removeAll operation. |
||||
*/ |
||||
boolean removeAll(Collection c); |
||||
|
||||
/** |
||||
* Remove all elements of this collection that are not contained in a given |
||||
* collection. That is, remove every element e such that !c.contains(e). |
||||
* |
||||
* @returns true if this collection was modified as a result of this call. |
||||
* @exception UnsupportedOperationException if this collection does not |
||||
* support the retainAll operation. |
||||
*/ |
||||
boolean retainAll(Collection c); |
||||
|
||||
/** |
||||
* Get the number of elements in this collection. |
||||
* |
||||
* @returns the number of elements in the collection. |
||||
*/ |
||||
int size(); |
||||
|
||||
/** |
||||
* Copy the current contents of this collection into an array. |
||||
* |
||||
* @returns an array of type Object[] and length equal to the size of this |
||||
* collection, containing the elements currently in this collection, in |
||||
* any order. |
||||
*/ |
||||
Object[] toArray(); |
||||
|
||||
/** |
||||
* Copy the current contents of this collection into an array. If the array |
||||
* passed as an argument has length less than the size of this collection, an |
||||
* array of the same run-time type as a, and length equal to the size of this |
||||
* collection, is allocated using Reflection. Otherwise, a itself is used. |
||||
* The elements of this collection are copied into it, and if there is space |
||||
* in the array, the following element is set to null. The resultant array is |
||||
* returned. |
||||
* Note: The fact that the following element is set to null is only useful |
||||
* if it is known that this collection does not contain any null elements. |
||||
* |
||||
* @param a the array to copy this collection into. |
||||
* @returns an array containing the elements currently in this collection, in |
||||
* any order. |
||||
* @exception ArrayStoreException if the type of any element of the |
||||
* collection is not a subtype of the element type of a. |
||||
*/ |
||||
Object[] toArray(Object[] a); |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -1,51 +0,0 @@ |
||||
// This interface is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/************************************************************************* |
||||
/* Comparable.java -- Interface for comparaing objects to obtain an ordering |
||||
/* |
||||
/* Copyright (c) 1998 by Free Software Foundation, Inc. |
||||
/* |
||||
/* This program is free software; you can redistribute it and/or modify |
||||
/* it under the terms of the GNU Library General Public License as published |
||||
/* by the Free Software Foundation, version 2. (see COPYING.LIB) |
||||
/* |
||||
/* This program is distributed in the hope that it will be useful, but |
||||
/* WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
/* GNU General Public License for more details. |
||||
/* |
||||
/* You should have received a copy of the GNU General Public License |
||||
/* along with this program; if not, write to the Free Software Foundation |
||||
/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA |
||||
/*************************************************************************/ |
||||
|
||||
package jode.util; |
||||
|
||||
/** |
||||
** Interface for objects that can be ordering among other |
||||
** objects. The ordering can be <EM>total</EM>, such that two objects |
||||
** only compare equal if they are equal by the equals method, or |
||||
** <EM>partial</EM> such that this is not necessarily true. For |
||||
** example, a case-sensitive dictionary order comparison of Strings |
||||
** is total, but if it is case-insensitive it is partial, because |
||||
** "abc" and "ABC" compare as equal even though "abc".equals("ABC") |
||||
** returns false. |
||||
** |
||||
** @author Geoff Berry |
||||
** |
||||
** @since JDK1.2 |
||||
** @see java.util.Comparator |
||||
**/ |
||||
public interface Comparable |
||||
{ |
||||
/** |
||||
** @return a negative integer if this object is less than |
||||
** <code>o<code>, zero if this object is equal to <code>o</code>, or |
||||
** a positive integer if this object is greater than <code>o</code> |
||||
**/ |
||||
public int compareTo( Object o ); |
||||
} |
@ -1,62 +0,0 @@ |
||||
// This interface is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Comparator.java -- Interface for objects that specify an ordering
|
||||
//
|
||||
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package jode.util; |
||||
|
||||
/** |
||||
* Interface for objects that specify an ordering between objects. The ordering |
||||
* can be <EM>total</EM>, such that two objects only compare equal if they are |
||||
* equal by the equals method, or <EM>partial</EM> such that this is not |
||||
* necessarily true. For example, a case-sensitive dictionary order comparison |
||||
* of Strings is total, but if it is case-insensitive it is partial, because |
||||
* "abc" and "ABC" compare as equal even though "abc".equals("ABC") returns |
||||
* false. |
||||
* <P> |
||||
* In general, Comparators should be Serializable, because when they are passed |
||||
* to Serializable data structures such as SortedMap or SortedSet, the entire |
||||
* data structure will only serialize correctly if the comparator is |
||||
* Serializable. |
||||
*/ |
||||
public interface Comparator { |
||||
|
||||
/** |
||||
* Return an integer that is negative, zero or positive depending on whether |
||||
* the first argument is less than, equal to or greater than the second |
||||
* according to this ordering. This method should obey the following contract: |
||||
* <UL> |
||||
* <LI>if compare(a, b) < 0 then compare(b, a) > 0</LI> |
||||
* <LI>if compare(a, b) throws an exception, so does compare(b, a)</LI> |
||||
* <LI>if compare(a, b) < 0 and compare(b, c) < 0 then compare(a, c) |
||||
* < 0</LI> |
||||
* <LI>if a.equals(b) or both a and b are null, then compare(a, b) == 0. |
||||
* The converse need not be true, but if it is, this Comparator |
||||
* specifies a <EM>total</EM> ordering.</LI> |
||||
* </UL> |
||||
* |
||||
* @throws ClassCastException if the elements are not of types that can be |
||||
* compared by this ordering. |
||||
*/ |
||||
int compare(Object o1, Object o2); |
||||
} |
@ -1,53 +0,0 @@ |
||||
// This interface is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// ConcurrentModificationException.java -- Data structure concurrently modified
|
||||
//
|
||||
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package jode.util; |
||||
|
||||
/** |
||||
* Exception that is thrown by the collections classes when it is detected that |
||||
* a modification has been made to a data structure when this is not allowed, |
||||
* such as when a collection is structurally modified while an Iterator is |
||||
* operating over it. In cases where this can be detected, a |
||||
* ConcurrentModificationException will be thrown. An Iterator that detects this |
||||
* condition is referred to as fail-fast. |
||||
*/ |
||||
public class ConcurrentModificationException extends RuntimeException { |
||||
|
||||
/** |
||||
* Constructs a ConcurrentModificationException with no detail message. |
||||
*/ |
||||
public ConcurrentModificationException() { |
||||
super(); |
||||
} |
||||
|
||||
/** |
||||
* Constructs a ConcurrentModificationException with a detail message. |
||||
* |
||||
* @param detail the detail message for the exception |
||||
*/ |
||||
public ConcurrentModificationException(String detail) { |
||||
super(detail); |
||||
} |
||||
} |
@ -1,876 +0,0 @@ |
||||
// This class is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// HashMap.java -- a class providing a basic hashtable data structure,
|
||||
// mapping Object --> Object; part of the JDK1.2 collections
|
||||
// API
|
||||
//
|
||||
// This is a JDK 1.2 compliant version of HashMap.java
|
||||
//
|
||||
// Copyright (c) 1998 by Jon A. Zeppieri (jon@eease.com),
|
||||
// Free Software Foundation, Inc.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
package jode.util; |
||||
import java.util.NoSuchElementException; |
||||
|
||||
import java.io.IOException; |
||||
import java.io.Serializable; |
||||
import java.io.ObjectInputStream; |
||||
import java.io.ObjectOutputStream; |
||||
|
||||
/** |
||||
* This class provides a hashtable-backed implementation of the |
||||
* Map interface. |
||||
* |
||||
* It uses a hash-bucket approach; that is, hash |
||||
* collisions are handled by linking the new node off of the |
||||
* pre-existing node (or list of nodes). In this manner, techniques |
||||
* such as linear probing (which can casue primary clustering) and |
||||
* rehashing (which does not fit very well with Java's method of |
||||
* precomputing hash codes) are avoided. |
||||
* |
||||
* Under ideal circumstances (no collisions, HashMap offers O(1) |
||||
* performance on most operations (<pre>containsValue()</pre> is, |
||||
* of course, O(n)). In the worst case (all keys map to the same |
||||
* hash code -- very unlikely), most operations are O(n). |
||||
* |
||||
* HashMap is part of the JDK1.2 Collections API. It differs from |
||||
* Hashtable in that it accepts the null key and null values, and it |
||||
* does not support "Enumeration views." |
||||
* |
||||
* @author Jon Zeppieri |
||||
* @version $Revision$ |
||||
* @modified $Id$ |
||||
*/ |
||||
public class HashMap extends AbstractMap |
||||
implements Map, Cloneable, Serializable |
||||
{ |
||||
// STATIC (CLASS) VARIABLES ------------------------------------------
|
||||
|
||||
/** |
||||
* the default capacity for an instance of HashMap -- I think this |
||||
* is low, and perhaps it shoudl be raised; Sun's documentation mildly |
||||
* suggests that this (11) is the correct value, though |
||||
*/ |
||||
private static final int DEFAULT_CAPACITY = 11; |
||||
|
||||
/** the default load factor of a HashMap */ |
||||
private static final float DEFAULT_LOAD_FACTOR = 0.75F; |
||||
|
||||
/** used internally to represent the null key */ |
||||
private static final HashMap.Null NULL_KEY = new HashMap.Null(); |
||||
|
||||
/** used internally to parameterize the creation of set/collection views */ |
||||
private static final int KEYS = 0; |
||||
|
||||
/** used internally to parameterize the creation of set/collection views */ |
||||
private static final int VALUES = 1; |
||||
|
||||
/** used internally to parameterize the creation of set/collection views */ |
||||
private static final int ENTRIES = 2; |
||||
|
||||
private static final long serialVersionUID = 362498820763181265L; |
||||
|
||||
// INSTANCE VARIABLES -------------------------------------------------
|
||||
|
||||
/** the capacity of this HashMap: denotes the size of the bucket array */ |
||||
transient int capacity; |
||||
|
||||
/** the size of this HashMap: denotes the number of key-value pairs */ |
||||
private transient int size; |
||||
|
||||
/** the load factor of this HashMap: used in computing the threshold |
||||
* @serial |
||||
*/ |
||||
float loadFactor; |
||||
|
||||
/* the rounded product of the capacity and the load factor; when the number of |
||||
* elements exceeds the threshold, the HashMap calls <pre>rehash()</pre> |
||||
* @serial |
||||
*/ |
||||
private int threshold; |
||||
|
||||
/** |
||||
* this data structure contains the actual key-value mappings; a |
||||
* <pre>BucketList</pre> is a lightweight linked list of "Buckets", |
||||
* which, in turn, are linked nodes containing a key-value mapping |
||||
* and a reference to the "next" Bucket in the list |
||||
*/ |
||||
private transient Bucket[] buckets; |
||||
|
||||
/** |
||||
* counts the number of modifications this HashMap has undergone; used by Iterators |
||||
* to know when to throw ConcurrentModificationExceptions (idea ripped-off from |
||||
* Stuart Ballard's AbstractList implementation) |
||||
*/ |
||||
private transient int modCount; |
||||
|
||||
|
||||
// CONSTRUCTORS ---------------------------------------------------------
|
||||
|
||||
/** |
||||
* construct a new HashMap with the default capacity and the default |
||||
* load factor |
||||
*/ |
||||
public HashMap() |
||||
{ |
||||
init(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR); |
||||
} |
||||
|
||||
/** |
||||
* construct a new HashMap with a specific inital capacity and load factor |
||||
* |
||||
* @param initialCapacity the initial capacity of this HashMap (>=0) |
||||
* @param initialLoadFactor the load factor of this HashMap |
||||
* (a misnomer, really, since the load factor of |
||||
* a HashMap does not change) |
||||
* |
||||
* @throws IllegalArgumentException if (initialCapacity < 0) || |
||||
* (initialLoadFactor > 1.0) || |
||||
* (initialLoadFactor <= 0.0) |
||||
*/ |
||||
public HashMap(int initialCapacity, float initialLoadFactor) |
||||
throws IllegalArgumentException |
||||
{ |
||||
if (initialCapacity < 0 || initialLoadFactor <= 0 || initialLoadFactor > 1) |
||||
throw new IllegalArgumentException(); |
||||
else |
||||
init(initialCapacity, initialLoadFactor); |
||||
} |
||||
|
||||
/** |
||||
* construct a new HashMap with a specific inital capacity |
||||
* |
||||
* @param initialCapacity the initial capacity of this HashMap (>=0) |
||||
* |
||||
* @throws IllegalArgumentException if (initialCapacity < 0) |
||||
*/ |
||||
public HashMap(int initialCapacity) |
||||
throws IllegalArgumentException |
||||
{ |
||||
if (initialCapacity < 0) |
||||
throw new IllegalArgumentException(); |
||||
else |
||||
init(initialCapacity, DEFAULT_LOAD_FACTOR); |
||||
} |
||||
|
||||
/** |
||||
* construct a new HashMap from the given Map |
||||
* |
||||
* every element in Map t will be put into this new HashMap |
||||
* |
||||
* @param t a Map whose key / value pairs will be put into |
||||
* the new HashMap. <b>NOTE: key / value pairs |
||||
* are not cloned in this constructor</b> |
||||
*/ |
||||
public HashMap(Map t) |
||||
{ |
||||
int mapSize = t.size() * 2; |
||||
init(((mapSize > DEFAULT_CAPACITY) ? mapSize : DEFAULT_CAPACITY), DEFAULT_LOAD_FACTOR); |
||||
putAll(t); |
||||
} |
||||
|
||||
|
||||
// PUBLIC METHODS ---------------------------------------------------------
|
||||
|
||||
/** returns the number of kay-value mappings currently in this Map */ |
||||
public int size() |
||||
{ |
||||
return size; |
||||
} |
||||
|
||||
/** returns true if there are no key-value mappings currently in this Map */ |
||||
public boolean isEmpty() |
||||
{ |
||||
return size == 0; |
||||
} |
||||
|
||||
/** empties this HashMap of all elements */ |
||||
public void clear() |
||||
{ |
||||
size = 0; |
||||
modCount++; |
||||
buckets = new Bucket[capacity]; |
||||
} |
||||
|
||||
/** |
||||
* returns a shallow clone of this HashMap (i.e. the Map itself is cloned, but |
||||
* its contents are not) |
||||
*/ |
||||
public Object clone() |
||||
{ |
||||
Map.Entry entry; |
||||
Iterator it = entrySet().iterator(); |
||||
HashMap clone = new HashMap(capacity, loadFactor); |
||||
while (it.hasNext()) |
||||
{ |
||||
entry = (Map.Entry) it.next(); |
||||
clone.internalPut(entry.getKey(), entry.getValue()); |
||||
} |
||||
return clone; |
||||
} |
||||
|
||||
/** returns a "set view" of this HashMap's keys */ |
||||
public Set keySet() |
||||
{ |
||||
return new HashMapSet(KEYS); |
||||
} |
||||
|
||||
/** returns a "set view" of this HashMap's entries */ |
||||
public Set entrySet() |
||||
{ |
||||
return new HashMapSet(ENTRIES); |
||||
} |
||||
|
||||
/** returns a "collection view" (or "bag view") of this HashMap's values */ |
||||
public Collection values() |
||||
{ |
||||
return new HashMapCollection(); |
||||
} |
||||
|
||||
/** |
||||
* returns true if the supplied object equals (<pre>equals()</pre>) a key |
||||
* in this HashMap |
||||
* |
||||
* @param key the key to search for in this HashMap |
||||
*/ |
||||
public boolean containsKey(Object key) |
||||
{ |
||||
return (internalGet(key) != null); |
||||
} |
||||
|
||||
/** |
||||
* returns true if this HashMap contains a value <pre>o</pre>, such that |
||||
* <pre>o.equals(value)</pre>. |
||||
* |
||||
* @param value the value to search for in this Hashtable |
||||
*/ |
||||
public boolean containsValue(Object value) |
||||
{ |
||||
int i; |
||||
Bucket list; |
||||
|
||||
for (i = 0; i < capacity; i++) |
||||
{ |
||||
list = buckets[i]; |
||||
if (list != null && list.containsValue(value)) |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/* |
||||
* return the value in this Hashtable associated with the supplied key, or <pre>null</pre> |
||||
* if the key maps to nothing |
||||
* |
||||
* @param key the key for which to fetch an associated value |
||||
*/ |
||||
public Object get(Object key) |
||||
{ |
||||
Map.Entry oResult = internalGet(key); |
||||
return (oResult == null) ? null : oResult.getValue(); |
||||
} |
||||
|
||||
/** |
||||
* puts the supplied value into the Map, mapped by the supplied key |
||||
* |
||||
* @param key the HashMap key used to locate the value |
||||
* @param value the value to be stored in the HashMap |
||||
*/ |
||||
public Object put(Object key, Object value) |
||||
{ |
||||
return internalPut(key, value); |
||||
} |
||||
|
||||
/** |
||||
* part of the Map interface; for each Map.Entry in t, the key / value pair is |
||||
* added to this Map, <b>using the <pre>put()</pre> method -- this may not be |
||||
* you want, so be warned (if you override the put() method, this could lead to |
||||
* off behavior)</b> |
||||
* |
||||
* @param t a Map whose key / value pairs will be added to this Hashtable |
||||
*/ |
||||
public void putAll(Map t) |
||||
{ |
||||
Map.Entry entry; |
||||
Iterator it = t.entrySet().iterator(); |
||||
while (it.hasNext()) |
||||
{ |
||||
entry = (Map.Entry) it.next(); |
||||
put(entry.getKey(), entry.getValue()); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* removes from the HashMap and returns the value which is mapped by the |
||||
* supplied key; if the key maps to nothing, then the HashMap remains unchanged, |
||||
* and <pre>null</pre> is returned |
||||
* |
||||
* @param key the key used to locate the value to remove from the HashMap |
||||
*/ |
||||
public Object remove(Object key) |
||||
{ |
||||
Bucket list; |
||||
int index; |
||||
Object result = null; |
||||
if (size > 0) |
||||
{ |
||||
index = hash(((key == null) ? NULL_KEY : key)); |
||||
list = buckets[index]; |
||||
if (list != null) |
||||
{ |
||||
result = list.removeByKey(key); |
||||
if (result != null) |
||||
{ |
||||
size--; |
||||
modCount++; |
||||
if (list.first == null) |
||||
buckets[index] = null; |
||||
} |
||||
} |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
|
||||
// PRIVATE METHODS -----------------------------------------------------------
|
||||
|
||||
/** |
||||
* puts the given key-value pair into this HashMap; a private method is used |
||||
* because it is called by the rehash() method as well as the put() method, |
||||
* and if a subclass overrides put(), then rehash would do funky things |
||||
* if it called put() |
||||
* |
||||
* @param key the HashMap key used to locate the value |
||||
* @param value the value to be stored in the HashMap |
||||
*/ |
||||
private Object internalPut(Object key, Object value) |
||||
{ |
||||
HashMapEntry entry; |
||||
Bucket list; |
||||
int hashIndex; |
||||
Object oResult; |
||||
Object oRealKey = ((key == null) ? NULL_KEY : key); |
||||
|
||||
modCount++; |
||||
if (size == threshold) |
||||
rehash(); |
||||
entry = new HashMapEntry(oRealKey, value); |
||||
hashIndex = hash(oRealKey); |
||||
list = buckets[hashIndex]; |
||||
if (list == null) |
||||
{ |
||||
list = new Bucket(); |
||||
buckets[hashIndex] = list; |
||||
} |
||||
oResult = list.add(entry); |
||||
if (oResult == null) |
||||
{ |
||||
size++; |
||||
return null; |
||||
} |
||||
else |
||||
{ |
||||
return ((Map.Entry) oResult).getValue(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* a private method, called by all of the constructors to initialize a new HashMap |
||||
* |
||||
* @param initialCapacity the initial capacity of this HashMap (>=0) |
||||
* @param initialLoadFactor the load factor of this HashMap |
||||
* (a misnomer, really, since the load factor of |
||||
* a HashMap does not change) |
||||
*/ |
||||
private void init(int initialCapacity, float initialLoadFactor) |
||||
{ |
||||
size = 0; |
||||
modCount = 0; |
||||
capacity = initialCapacity; |
||||
loadFactor = initialLoadFactor; |
||||
threshold = (int) ((float) capacity * loadFactor); |
||||
buckets = new Bucket[capacity]; |
||||
} |
||||
|
||||
/** private -- simply hashes a non-null Object to its array index */ |
||||
private int hash(Object key) |
||||
{ |
||||
return Math.abs(key.hashCode() % capacity); |
||||
} |
||||
|
||||
/** |
||||
* increases the size of the HashMap and rehashes all keys to new array indices; |
||||
* this is called when the addition of a new value would cause size() > threshold |
||||
*/ |
||||
private void rehash() |
||||
{ |
||||
int i; |
||||
Bucket[] data = buckets; |
||||
Bucket.Node node; |
||||
|
||||
modCount++; |
||||
capacity = (capacity * 2) + 1; |
||||
size = 0; |
||||
threshold = (int) ((float) capacity * loadFactor); |
||||
buckets = new Bucket[capacity]; |
||||
for (i = 0; i < data.length; i++) |
||||
{ |
||||
if (data[i] != null) |
||||
{ |
||||
node = data[i].first; |
||||
while (node != null) |
||||
{ |
||||
internalPut(node.getKey(), node.getValue()); |
||||
node = node.next; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* a private method which does the "dirty work" (or some of it anyway) of fetching a value |
||||
* with a key |
||||
* |
||||
* @param key the key for which to fetch an associated value |
||||
*/ |
||||
private Map.Entry internalGet(Object key) |
||||
{ |
||||
Bucket list; |
||||
if (size == 0) |
||||
{ |
||||
return null; |
||||
} |
||||
else |
||||
{ |
||||
list = buckets[hash(((key == null) ? NULL_KEY : key))]; |
||||
return (list == null) ? null : list.getEntryByKey(key); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* a private method used by inner class HashMapSet to implement its own |
||||
* <pre>contains(Map.Entry)</pre> method; returns true if the supplied |
||||
* key / value pair is found in this HashMap (again, using <pre>equals()</pre>, |
||||
* rather than <pre>==</pre>) |
||||
* |
||||
* @param entry a Map.Entry to match against key / value pairs in |
||||
* this HashMap |
||||
*/ |
||||
private boolean containsEntry(Map.Entry entry) |
||||
{ |
||||
Map.Entry oInternalEntry; |
||||
if (entry == null) |
||||
{ |
||||
return false; |
||||
} |
||||
else |
||||
{ |
||||
oInternalEntry = internalGet(entry.getKey()); |
||||
return (oInternalEntry != null && oInternalEntry.equals(entry)); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Serializes this object to the given stream. |
||||
* @serialdata the <i>capacity</i>(int) that is the length of the |
||||
* bucket array, the <i>size</i>(int) of the hash map are emitted |
||||
* first. They are followed by size entries, each consisting of |
||||
* a key (Object) and a value (Object). |
||||
*/ |
||||
private void writeObject(ObjectOutputStream s) |
||||
throws IOException |
||||
{ |
||||
// the fields
|
||||
s.defaultWriteObject(); |
||||
|
||||
s.writeInt(capacity); |
||||
s.writeInt(size); |
||||
Iterator it = entrySet().iterator(); |
||||
while (it.hasNext()) |
||||
{ |
||||
Map.Entry oEntry = (Map.Entry) it.next(); |
||||
s.writeObject(oEntry.getKey()); |
||||
s.writeObject(oEntry.getValue()); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Deserializes this object from the given stream. |
||||
* @serialdata the <i>capacity</i>(int) that is the length of the |
||||
* bucket array, the <i>size</i>(int) of the hash map are emitted |
||||
* first. They are followed by size entries, each consisting of |
||||
* a key (Object) and a value (Object). |
||||
*/ |
||||
private void readObject(ObjectInputStream s) |
||||
throws IOException, ClassNotFoundException |
||||
{ |
||||
// the fields
|
||||
s.defaultReadObject(); |
||||
|
||||
capacity = s.readInt(); |
||||
int iLen = s.readInt(); |
||||
size = 0; |
||||
modCount = 0; |
||||
buckets = new Bucket[capacity]; |
||||
|
||||
for (int i = 0; i < iLen; i++) |
||||
{ |
||||
Object oKey = s.readObject(); |
||||
Object oValue = s.readObject(); |
||||
internalPut(oKey, oValue); |
||||
} |
||||
} |
||||
|
||||
// INNER CLASSES -------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/** |
||||
* an inner class providing a Set view of a HashMap; this implementation is |
||||
* parameterized to view either a Set of keys or a Set of Map.Entry objects |
||||
* |
||||
* Note: a lot of these methods are implemented by AbstractSet, and would work |
||||
* just fine without any meddling, but far greater efficiency can be gained by |
||||
* overriding a number of them. And so I did. |
||||
* |
||||
* @author Jon Zeppieri |
||||
* @version $Revision$ |
||||
* @modified $Id$ |
||||
*/ |
||||
private class HashMapSet extends AbstractSet |
||||
implements Set |
||||
{ |
||||
/** the type of this Set view: KEYS or ENTRIES */ |
||||
private int setType; |
||||
|
||||
/** construct a new HashtableSet with the supplied view type */ |
||||
HashMapSet(int type) |
||||
{ |
||||
setType = type; |
||||
} |
||||
|
||||
/** |
||||
* adding an element is unsupported; this method simply throws an exception |
||||
* |
||||
* @throws UnsupportedOperationException |
||||
*/ |
||||
public boolean add(Object o) throws UnsupportedOperationException |
||||
{ |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
/** |
||||
* adding an element is unsupported; this method simply throws an exception |
||||
* |
||||
* @throws UnsupportedOperationException |
||||
*/ |
||||
public boolean addAll(Collection c) throws UnsupportedOperationException |
||||
{ |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
/** |
||||
* clears the backing HashMap; this is a prime example of an overridden implementation |
||||
* which is far more efficient than its superclass implementation (which uses an iterator |
||||
* and is O(n) -- this is an O(1) call) |
||||
*/ |
||||
public void clear() |
||||
{ |
||||
HashMap.this.clear(); |
||||
} |
||||
|
||||
/** |
||||
* returns true if the supplied object is contained by this Set |
||||
* |
||||
* @param o an Object being testing to see if it is in this Set |
||||
*/ |
||||
public boolean contains(Object o) |
||||
{ |
||||
if (setType == KEYS) |
||||
return HashMap.this.containsKey(o); |
||||
else |
||||
return (o instanceof Map.Entry) ? HashMap.this.containsEntry((Map.Entry) o) : false; |
||||
} |
||||
|
||||
/** |
||||
* returns true if the backing HashMap is empty (which is the only case either a KEYS |
||||
* Set or an ENTRIES Set would be empty) |
||||
*/ |
||||
public boolean isEmpty() |
||||
{ |
||||
return HashMap.this.isEmpty(); |
||||
} |
||||
|
||||
/** |
||||
* removes the supplied Object from the Set |
||||
* |
||||
* @param o the Object to be removed |
||||
*/ |
||||
public boolean remove(Object o) |
||||
{ |
||||
if (setType == KEYS) |
||||
return (HashMap.this.remove(o) != null); |
||||
else |
||||
return (o instanceof Map.Entry) ? |
||||
(HashMap.this.remove(((Map.Entry) o).getKey()) != null) : false; |
||||
} |
||||
|
||||
/** returns the size of this Set (always equal to the size of the backing Hashtable) */ |
||||
public int size() |
||||
{ |
||||
return HashMap.this.size(); |
||||
} |
||||
|
||||
/** returns an Iterator over the elements of this Set */ |
||||
public Iterator iterator() |
||||
{ |
||||
return new HashMapIterator(setType); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Like the above Set view, except this one if for values, which are not |
||||
* guaranteed to be unique in a Map; this prvides a Bag of values |
||||
* in the HashMap |
||||
* |
||||
* @author Jon Zeppieri |
||||
* @version $Revision$ |
||||
* @modified $Id$ |
||||
*/ |
||||
private class HashMapCollection extends AbstractCollection |
||||
implements Collection |
||||
{ |
||||
/** a trivial contructor for HashMapCollection */ |
||||
HashMapCollection() |
||||
{ |
||||
} |
||||
|
||||
/** |
||||
* adding elements is not supported by this Collection; |
||||
* this method merely throws an exception |
||||
* |
||||
* @throws UnsupportedOperationException |
||||
*/ |
||||
public boolean add(Object o) throws UnsupportedOperationException |
||||
{ |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
/** |
||||
* adding elements is not supported by this Collection; |
||||
* this method merely throws an exception |
||||
* |
||||
* @throws UnsupportedOperationException |
||||
*/ |
||||
public boolean addAll(Collection c) throws UnsupportedOperationException |
||||
{ |
||||
throw new UnsupportedOperationException(); |
||||
} |
||||
|
||||
/** removes all elements from this Collection (and from the backing HashMap) */ |
||||
public void clear() |
||||
{ |
||||
HashMap.this.clear(); |
||||
} |
||||
|
||||
/** |
||||
* returns true if this Collection contains at least one Object which equals() the |
||||
* supplied Object |
||||
* |
||||
* @param o the Object to compare against those in the Set |
||||
*/ |
||||
public boolean contains(Object o) |
||||
{ |
||||
return HashMap.this.containsValue(o); |
||||
} |
||||
|
||||
/** returns true IFF the Collection has no elements */ |
||||
public boolean isEmpty() |
||||
{ |
||||
return HashMap.this.isEmpty(); |
||||
} |
||||
|
||||
/** returns the size of this Collection */ |
||||
public int size() |
||||
{ |
||||
return HashMap.this.size(); |
||||
} |
||||
|
||||
/** returns an Iterator over the elements in this Collection */ |
||||
public Iterator iterator() |
||||
{ |
||||
return new HashMapIterator(VALUES); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* a class which implements the Iterator interface and is used for |
||||
* iterating over HashMaps; |
||||
* this implementation is parameterized to give a sequential view of |
||||
* keys, values, or entries; it also allows the removal of elements, |
||||
* as per the Javasoft spec. |
||||
* |
||||
* @author Jon Zeppieri |
||||
* @version $Revision$ |
||||
* @modified $Id$ |
||||
*/ |
||||
class HashMapIterator implements Iterator |
||||
{ |
||||
/** the type of this Iterator: KEYS, VALUES, or ENTRIES */ |
||||
private int myType; |
||||
/** |
||||
* the number of modifications to the backing Hashtable for which |
||||
* this Iterator can account (idea ripped off from Stuart Ballard) |
||||
*/ |
||||
private int knownMods; |
||||
/** the location of our sequential "cursor" */ |
||||
private int position; |
||||
/** the current index of the BucketList array */ |
||||
private int bucketIndex; |
||||
/** a reference, originally null, to the specific Bucket our "cursor" is pointing to */ |
||||
private Bucket.Node currentNode; |
||||
/** a reference to the current key -- used fro removing elements via the Iterator */ |
||||
private Object currentKey; |
||||
|
||||
/** construct a new HashtableIterator with the supllied type: KEYS, VALUES, or ENTRIES */ |
||||
HashMapIterator(int type) |
||||
{ |
||||
myType = type; |
||||
knownMods = HashMap.this.modCount; |
||||
position = 0; |
||||
bucketIndex = -1; |
||||
currentNode = null; |
||||
currentKey = null; |
||||
} |
||||
|
||||
/** |
||||
* Stuart Ballard's code: if the backing HashMap has been altered through anything |
||||
* but <i>this</i> Iterator's <pre>remove()</pre> method, we will give up right here, |
||||
* rather than risking undefined behavior |
||||
* |
||||
* @throws ConcurrentModificationException |
||||
*/ |
||||
private void checkMod() |
||||
{ |
||||
if (knownMods != HashMap.this.modCount) |
||||
throw new ConcurrentModificationException(); |
||||
} |
||||
|
||||
/** returns true if the Iterator has more elements */ |
||||
public boolean hasNext() |
||||
{ |
||||
checkMod(); |
||||
return position < HashMap.this.size(); |
||||
} |
||||
|
||||
/** returns the next element in the Iterator's sequential view */ |
||||
public Object next() |
||||
{ |
||||
Bucket list = null; |
||||
Object result; |
||||
checkMod(); |
||||
try |
||||
{ |
||||
while (currentNode == null) |
||||
{ |
||||
while (list == null) |
||||
list = HashMap.this.buckets[++bucketIndex]; |
||||
currentNode = list.first; |
||||
} |
||||
currentKey = currentNode.getKey(); |
||||
result = (myType == KEYS) ? currentKey : |
||||
((myType == VALUES) ? currentNode.getValue() : currentNode); |
||||
currentNode = currentNode.next; |
||||
} |
||||
catch(Exception e) |
||||
{ |
||||
throw new NoSuchElementException(); |
||||
} |
||||
position++; |
||||
return result; |
||||
} |
||||
|
||||
/** |
||||
* removes from the backing HashMap the last element which was fetched with the |
||||
* <pre>next()</pre> method |
||||
*/ |
||||
public void remove() |
||||
{ |
||||
checkMod(); |
||||
if (currentKey == null) |
||||
{ |
||||
throw new IllegalStateException(); |
||||
} |
||||
else |
||||
{ |
||||
HashMap.this.remove(currentKey); |
||||
knownMods++; |
||||
currentKey = null; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* a singleton instance of this class (HashMap.NULL_KEY) |
||||
* is used to represent the null key in HashMap objects |
||||
* |
||||
* @author Jon Zeppieri |
||||
* @version $Revision$ |
||||
* @modified $Id$ |
||||
*/ |
||||
private static class Null |
||||
{ |
||||
/** trivial constructor */ |
||||
Null() |
||||
{ |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* a HashMap version of Map.Entry -- one thing in this implementation is |
||||
* HashMap-specific: if the key is HashMap.NULL_KEY, getKey() will return |
||||
* null |
||||
* |
||||
* Simply, a key / value pair |
||||
* |
||||
* @author Jon Zeppieri |
||||
* @version $Revision$ |
||||
* @modified $Id$ |
||||
*/ |
||||
private static class HashMapEntry extends Bucket.Node implements Map.Entry |
||||
{ |
||||
/** construct a new HashMapEntry with the given key and value */ |
||||
public HashMapEntry(Object key, Object value) |
||||
{ |
||||
super(key, value); |
||||
} |
||||
|
||||
/** |
||||
* if the key == HashMap.NULL_KEY, null is returned, otherwise the actual |
||||
* key is returned |
||||
*/ |
||||
public Object getKey() |
||||
{ |
||||
Object oResult = super.getKey(); |
||||
return (oResult == HashMap.NULL_KEY) ? null : oResult; |
||||
} |
||||
} |
||||
// EOF -----------------------------------------------------------------------
|
||||
} |
@ -1,238 +0,0 @@ |
||||
// This class is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// HashSet.java -- a class providing a HashMap-backet Set
|
||||
//
|
||||
// Copyright (c) 1998 by Jon A. Zeppieri (jon@eease.com)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
package jode.util; |
||||
|
||||
import java.io.IOException; |
||||
import java.io.Serializable; |
||||
import java.io.ObjectInputStream; |
||||
import java.io.ObjectOutputStream; |
||||
|
||||
/** |
||||
* This class provides a HashMap-backed implementation of the |
||||
* Set interface. |
||||
* |
||||
* Each element in the Set is a key in the backing HashMap; each key |
||||
* maps to a static token, denoting that the key does, in fact, exist. |
||||
* |
||||
* Most operations are O(1), assuming no hash collisions. In the worst |
||||
* case (where all hases collide), operations are O(n). |
||||
* |
||||
* HashSet is a part of the JDK1.2 Collections API. |
||||
* |
||||
* @author Jon Zeppieri |
||||
* @version $Revision$ |
||||
* @modified $Id$ |
||||
*/ |
||||
public class HashSet extends AbstractSet |
||||
implements Set, Cloneable, Serializable |
||||
{ |
||||
// INSTANCE VARIABLES -------------------------------------------------
|
||||
/** the HashMap which backs this Set */ |
||||
private transient HashMap map; |
||||
static final long serialVersionUID = -5024744406713321676L; |
||||
|
||||
// CONSTRUCTORS ---------------------------------------------------------
|
||||
|
||||
/** |
||||
* construct a new, empty HashSet whose backing HashMap has the default |
||||
* capacity and loadFacor |
||||
*/ |
||||
public HashSet() |
||||
{ |
||||
map = new HashMap(); |
||||
} |
||||
|
||||
/** |
||||
* construct a new, empty HashSet whose backing HashMap has the supplied |
||||
* capacity and the default load factor |
||||
* |
||||
* @param initialCapacity the initial capacity of the backing |
||||
* HashMap |
||||
*/ |
||||
public HashSet(int initialCapacity) |
||||
{ |
||||
map = new HashMap(initialCapacity); |
||||
} |
||||
|
||||
/** |
||||
* construct a new, empty HashSet whose backing HashMap has the supplied |
||||
* capacity and load factor |
||||
* |
||||
* @param initialCapacity the initial capacity of the backing |
||||
* HashMap |
||||
* @param loadFactor the load factor of the backing HashMap |
||||
*/ |
||||
public HashSet(int initialCapacity, float loadFactor) |
||||
{ |
||||
map = new HashMap(initialCapacity, loadFactor); |
||||
} |
||||
|
||||
/** |
||||
* construct a new HashSet with the same elements as are in the supplied |
||||
* collection (eliminating any duplicates, of course; the backing HashMap |
||||
* will have the default capacity and load factor |
||||
* |
||||
* @param c a collection containing the elements with |
||||
* which this set will be initialized |
||||
*/ |
||||
public HashSet(Collection c) |
||||
{ |
||||
map = new HashMap(); |
||||
addAll(c); |
||||
} |
||||
|
||||
|
||||
// PUBLIC METHODS ---------------------------------------------------------
|
||||
|
||||
/** |
||||
* adds the given Object to the set if it is not already in the Set, |
||||
* returns true if teh element was added, false otherwise |
||||
* |
||||
* @param o the Object to add to this Set |
||||
*/ |
||||
public boolean add(Object o) |
||||
{ |
||||
if (map.containsKey(o)) |
||||
{ |
||||
return false; |
||||
} |
||||
else |
||||
{ |
||||
internalAdd(o); |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* empties this Set of all elements; this is a fast operation [O(1)] |
||||
*/ |
||||
public void clear() |
||||
{ |
||||
map.clear(); |
||||
} |
||||
|
||||
/** |
||||
* returns a shallow copy of this Set (the Set itself is cloned; its |
||||
* elements are not) |
||||
*/ |
||||
public Object clone() |
||||
{ |
||||
Iterator it = iterator(); |
||||
HashSet clone = new HashSet(map.capacity, map.loadFactor); |
||||
while (it.hasNext()) |
||||
clone.internalAdd(it.next()); |
||||
return clone; |
||||
} |
||||
|
||||
/** |
||||
* returns true if the supplied element is in this Set, false otherwise |
||||
* |
||||
* @param o the Object whose presence in this Set we are testing for |
||||
*/ |
||||
public boolean contains(Object o) |
||||
{ |
||||
return map.containsKey(o); |
||||
} |
||||
|
||||
/** |
||||
* returns true if this set has no elements in it (size() == 0) |
||||
*/ |
||||
public boolean isEmpty() |
||||
{ |
||||
return map.isEmpty(); |
||||
} |
||||
|
||||
/** |
||||
* returns an Iterator over the elements of this Set; the Iterator allows |
||||
* removal of elements |
||||
*/ |
||||
public Iterator iterator() |
||||
{ |
||||
return map.keySet().iterator(); |
||||
} |
||||
|
||||
/** |
||||
* removes the supplied Object from this Set if it is in the Set; returns |
||||
* true if an element was removed, false otherwise |
||||
*/ |
||||
public boolean remove(Object o) |
||||
{ |
||||
return (map.remove(o) != null); |
||||
} |
||||
|
||||
/** |
||||
* returns the number of elements in this Set |
||||
*/ |
||||
public int size() |
||||
{ |
||||
return map.size(); |
||||
} |
||||
|
||||
|
||||
// PRIVATE METHODS -----------------------------------------------------------
|
||||
|
||||
/** |
||||
* adds the supplied element to this Set; this private method is used |
||||
* internally [clone()] instead of add(), because add() can be overridden |
||||
* to do unexpected things |
||||
* |
||||
* @param o the Object to add to this Set |
||||
*/ |
||||
private void internalAdd(Object o) |
||||
{ |
||||
map.put(o, Boolean.TRUE); |
||||
} |
||||
|
||||
/** Serialize this Object in a manner which is binary-compatible with the JDK */ |
||||
private void writeObject(ObjectOutputStream s) throws IOException |
||||
{ |
||||
Iterator it = iterator(); |
||||
s.writeInt(map.capacity); |
||||
s.writeFloat(map.loadFactor); |
||||
s.writeInt(size()); |
||||
while (it.hasNext()) |
||||
s.writeObject(it.next()); |
||||
} |
||||
|
||||
/** Deserialize this Object in a manner which is binary-compatible with the JDK */ |
||||
private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException |
||||
{ |
||||
int i, iSize, iCapacity; |
||||
float fLoadFactor; |
||||
Object oElement; |
||||
|
||||
iCapacity = s.readInt(); |
||||
fLoadFactor = s.readFloat(); |
||||
iSize = s.readInt(); |
||||
|
||||
map = new HashMap(iCapacity, fLoadFactor); |
||||
|
||||
for (i = 0; i < iSize; i++) |
||||
{ |
||||
oElement = s.readObject(); |
||||
internalAdd(oElement); |
||||
} |
||||
} |
||||
} |
@ -1,66 +0,0 @@ |
||||
// This interface is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Iterator.java -- Interface for iterating over collections
|
||||
//
|
||||
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package jode.util; |
||||
|
||||
/** |
||||
* An object which iterates over a collection. An Iterator is used to return the |
||||
* items once only, in sequence, by successive calls to the next method. It is |
||||
* also possible to remove elements from the underlying collection by using the |
||||
* optional remove method. Iterator is intended as a replacement for the |
||||
* Enumeration interface of previous versions of Java, which did not have the |
||||
* remove method and had less conveniently named methods. |
||||
*/ |
||||
public interface Iterator { |
||||
|
||||
/** |
||||
* Tests whether there are elements remaining in the collection. |
||||
* |
||||
* @return true if there is at least one more element in the collection, |
||||
* that is, if the next call to next will not throw NoSuchElementException. |
||||
*/ |
||||
boolean hasNext(); |
||||
|
||||
/** |
||||
* Obtain the next element in the collection. |
||||
* |
||||
* @return the next element in the collection |
||||
* @exception NoSuchElementException if there are no more elements |
||||
*/ |
||||
Object next(); |
||||
|
||||
/** |
||||
* Remove from the underlying collection the last element returned by next. |
||||
* This method can be called only once after each call to next. It does not |
||||
* affect what will be returned by subsequent calls to next. This operation is |
||||
* optional, it may throw an UnsupportedOperationException. |
||||
* |
||||
* @exception IllegalStateException if next has not yet been called or remove |
||||
* has already been called since the last call to next. |
||||
* @exception UnsupportedOperationException if this Iterator does not support |
||||
* the remove operation. |
||||
*/ |
||||
void remove(); |
||||
} |
@ -1,581 +0,0 @@ |
||||
// This class is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// LinkedList.java -- Linked list implementation of the List interface
|
||||
//
|
||||
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package jode.util; |
||||
import java.util.NoSuchElementException; |
||||
import java.io.Serializable; |
||||
import java.io.ObjectOutputStream; |
||||
import java.io.ObjectInputStream; |
||||
import java.io.IOException; |
||||
|
||||
// TO DO:
|
||||
// ~ Doc comment for the class.
|
||||
// ~ Doc comments for the non-list methods.
|
||||
// ~ Some commenting on the Backing API and other general implementation notes.
|
||||
|
||||
/** |
||||
* Linked list implementation of the List interface. |
||||
*/ |
||||
public class LinkedList extends AbstractSequentialList |
||||
implements Serializable, Cloneable |
||||
{ |
||||
static final long serialVersionUID = 876323262645176354L; |
||||
|
||||
/** |
||||
* An Entry containing the head (in the next field) and the tail (in the |
||||
* previous field) of the list. The data field is null. If the list is empty, |
||||
* both the head and the tail point to ends itself. |
||||
*/ |
||||
transient Entry ends = new Entry(); |
||||
|
||||
/** |
||||
* The current length of the list. |
||||
*/ |
||||
transient int size = 0; |
||||
|
||||
/** |
||||
* Class to represent an entry in the list. Holds a single element. |
||||
*/ |
||||
private static class Entry { |
||||
|
||||
/** |
||||
* The list element. |
||||
*/ |
||||
Object data = null; |
||||
|
||||
/** |
||||
* The next entry in the list. If this is the last entry in the list, the |
||||
* ends field of the list is held here. |
||||
*/ |
||||
Entry next; |
||||
|
||||
/** |
||||
* The previous entry in the list. If this is the first entry in the list, |
||||
* the ends field of the list is held here. |
||||
*/ |
||||
Entry previous; |
||||
|
||||
/** |
||||
* Create an entry with given data and linkage. |
||||
*/ |
||||
Entry(Object d, Entry n, Entry p) { |
||||
data = d; |
||||
next = n; |
||||
previous = p; |
||||
} |
||||
|
||||
/** |
||||
* Create an entry with no data and linking to itself, for use as the ends |
||||
* field of the list. |
||||
*/ |
||||
Entry() { |
||||
next = previous = this; |
||||
} |
||||
|
||||
/** |
||||
* Remove this entry. |
||||
*/ |
||||
Object remove() { |
||||
previous.next = next; |
||||
next.previous = previous; |
||||
return data; |
||||
} |
||||
} |
||||
|
||||
private static interface Backing { |
||||
void checkMod(int known); |
||||
void upMod(); |
||||
void incSize(int by); |
||||
void decSize(int by); |
||||
} |
||||
|
||||
private final Backing back = new Backing() { |
||||
public void checkMod(int known) { |
||||
if (known != modCount) { |
||||
throw new ConcurrentModificationException(); |
||||
} |
||||
} |
||||
public void upMod() { |
||||
modCount++; |
||||
} |
||||
public void incSize(int by) { |
||||
size += by; |
||||
} |
||||
public void decSize(int by) { |
||||
size -= by; |
||||
} |
||||
}; |
||||
|
||||
/** A ListIterator over the list. This class keeps track of its |
||||
* position in the list, the size of the list, and the two list |
||||
* entries it is between. This enables it to be used identically |
||||
* for both the list itself and a sublist of the list. |
||||
*/ |
||||
private static class Iter implements ListIterator { |
||||
|
||||
/** |
||||
* The index of the element that will be returned by next(). |
||||
*/ |
||||
int pos; |
||||
|
||||
/** |
||||
* The size of the backing list. |
||||
*/ |
||||
int size; |
||||
|
||||
/** |
||||
* The entry containing the element that will be returned by next(). |
||||
*/ |
||||
Entry next; |
||||
|
||||
/** |
||||
* The entry containing the element that will be returned by previous(). |
||||
*/ |
||||
Entry previous; |
||||
|
||||
/** |
||||
* The entry that will be affected by remove() or set(). |
||||
*/ |
||||
Entry recent; |
||||
|
||||
/** |
||||
* The known value of the modCount of the backing list. |
||||
*/ |
||||
int knownMod; |
||||
|
||||
private final Backing b; |
||||
|
||||
/** |
||||
* Create a new Iter starting at a given Entry within the list, at a given |
||||
* position, in a list of given size. |
||||
* |
||||
* @param index the index to begin iteration. |
||||
* @exception IndexOutOfBoundsException if index < 0 || index > size. |
||||
*/ |
||||
Iter(Backing backing, Entry n, int index, int s, int mc) { |
||||
b = backing; |
||||
pos = index; |
||||
size = s; |
||||
next = n; |
||||
previous = n.previous; |
||||
knownMod = mc; |
||||
} |
||||
|
||||
public int nextIndex() { |
||||
b.checkMod(knownMod); |
||||
return pos; |
||||
} |
||||
|
||||
public int previousIndex() { |
||||
b.checkMod(knownMod); |
||||
return pos - 1; |
||||
} |
||||
|
||||
public boolean hasNext() { |
||||
b.checkMod(knownMod); |
||||
return pos < size; |
||||
} |
||||
|
||||
public boolean hasPrevious() { |
||||
b.checkMod(knownMod); |
||||
return pos > 0; |
||||
} |
||||
|
||||
public Object next() { |
||||
b.checkMod(knownMod); |
||||
if (pos >= size) { |
||||
throw new NoSuchElementException(); |
||||
} else { |
||||
pos++; |
||||
recent = previous = next; |
||||
next = recent.next; |
||||
return recent.data; |
||||
} |
||||
} |
||||
|
||||
public Object previous() { |
||||
b.checkMod(knownMod); |
||||
if (pos <= 0) { |
||||
throw new NoSuchElementException(); |
||||
} else { |
||||
pos--; |
||||
recent = next = previous; |
||||
previous = recent.previous; |
||||
return recent.data; |
||||
} |
||||
} |
||||
|
||||
public void remove() { |
||||
b.checkMod(knownMod); |
||||
if (recent == null) { |
||||
throw new IllegalStateException(); |
||||
} |
||||
|
||||
// Adjust the position to before the removed element
|
||||
if (recent == previous) pos--; |
||||
|
||||
// Could use recent.remove() but this way is quicker, and also correctly
|
||||
// fixes next and previous.
|
||||
next = recent.previous.next = recent.next; |
||||
previous = recent.next.previous = recent.previous; |
||||
size--; |
||||
b.decSize(1); |
||||
knownMod++; |
||||
b.upMod(); |
||||
recent = null; |
||||
} |
||||
|
||||
public void add(Object o) { |
||||
b.checkMod(knownMod); |
||||
previous.next = next.previous = new Entry(o, next, previous); |
||||
|
||||
// New for 1.2RC1 - the semantics changed so that the iterator is
|
||||
// positioned *after* the new element.
|
||||
previous = next; |
||||
next = previous.next; |
||||
pos++; |
||||
|
||||
size++; |
||||
b.incSize(1); |
||||
knownMod++; |
||||
b.upMod(); |
||||
recent = null; |
||||
} |
||||
|
||||
public void set(Object o) { |
||||
b.checkMod(knownMod); |
||||
if (recent == null) { |
||||
throw new IllegalStateException(); |
||||
} |
||||
recent.data = o; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Obtain the Entry at a given position in a list. This method of course |
||||
* takes linear time, but it is intelligent enough to take the shorter of the |
||||
* paths to get to the Entry required. This implies that the first or last |
||||
* entry in the list is obtained in constant time, which is a very desirable |
||||
* property. |
||||
* For speed and flexibility in which ranges are valid, range checking is not |
||||
* done in this method, and if n is outside the range -1 <= n <= size, the |
||||
* result will be wrong (but no exception will be thrown). |
||||
* Note that you *can* obtain entries at position -1 and size, which are |
||||
* equal to prehead and posttail respectively. |
||||
* This method is static so that it can also be used in subList. |
||||
* |
||||
* @param n the number of the entry to get. |
||||
* @param size the size of the list to get the entry in. |
||||
* @param head the entry before the first element of the list (usually ends). |
||||
* @param tail the entry after the last element of the list (usually ends). |
||||
*/ |
||||
static Entry getEntry(int n, int size, Entry head, Entry tail) { |
||||
|
||||
// n less than size/2, iterate from start
|
||||
if (n < size >> 1) { |
||||
while (n-- >= 0) { |
||||
head = head.next; |
||||
} |
||||
return head; |
||||
|
||||
// n greater than size/2, iterate from end
|
||||
} else { |
||||
while (++n <= size) { |
||||
tail = tail.previous; |
||||
} |
||||
return tail; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Create an empty linked list. |
||||
*/ |
||||
public LinkedList() { |
||||
super(); |
||||
} |
||||
|
||||
/** |
||||
* Create a linked list containing the elements, in order, of a given |
||||
* collection. |
||||
* |
||||
* @param c the collection to populate this list from. |
||||
*/ |
||||
public LinkedList(Collection c) { |
||||
super(); |
||||
// Note: addAll could be made slightly faster, but not enough so to justify
|
||||
// re-implementing it from scratch. It is just a matter of a relatively
|
||||
// small constant factor.
|
||||
addAll(c); |
||||
} |
||||
|
||||
public Object getFirst() { |
||||
if (size == 0) { |
||||
throw new NoSuchElementException(); |
||||
} |
||||
return ends.next.data; |
||||
} |
||||
|
||||
public Object getLast() { |
||||
if (size == 0) { |
||||
throw new NoSuchElementException(); |
||||
} |
||||
return ends.previous.data; |
||||
} |
||||
|
||||
public Object removeFirst() { |
||||
if (size == 0) { |
||||
throw new NoSuchElementException(); |
||||
} |
||||
size--; |
||||
modCount++; |
||||
return ends.next.remove(); |
||||
} |
||||
|
||||
public Object removeLast() { |
||||
if (size == 0) { |
||||
throw new NoSuchElementException(); |
||||
} |
||||
size--; |
||||
modCount++; |
||||
return ends.previous.remove(); |
||||
} |
||||
|
||||
public void addFirst(Object o) { |
||||
ends.next.previous = ends.next = new Entry(o, ends.next, ends); |
||||
size++; |
||||
modCount++; |
||||
} |
||||
|
||||
public void addLast(Object o) { |
||||
ends.previous.next = ends.previous = new Entry(o, ends, ends.previous); |
||||
size++; |
||||
modCount++; |
||||
} |
||||
|
||||
/** |
||||
* Obtain the number of elements currently in this list. |
||||
* |
||||
* @returns the number of elements currently in this list. |
||||
*/ |
||||
public int size() { |
||||
return size; |
||||
} |
||||
|
||||
/** |
||||
* Remove a range of elements from this list. |
||||
* |
||||
* @param fromIndex the index, inclusive, to remove from. |
||||
* @param toIndex the index, exclusive, to remove to. |
||||
* @exception IndexOutOfBoundsException if fromIndex > toIndex || fromIndex < |
||||
* 0 || toIndex > size(). |
||||
*/ |
||||
// Note: normally removeRange is provided to allow efficient ways to
|
||||
// implement clear() on subLists. However, in this case clear on subLists
|
||||
// works anyway, so this implementation is included just for completeness
|
||||
// and because subclasses might try to use it.
|
||||
protected void removeRange(int fromIndex, int toIndex) { |
||||
subList(fromIndex, toIndex).clear(); |
||||
} |
||||
|
||||
/** |
||||
* Clear the list. |
||||
*/ |
||||
public void clear() { |
||||
ends.next = ends.previous = ends; |
||||
modCount++; |
||||
size = 0; |
||||
} |
||||
|
||||
/** |
||||
* Obtain a ListIterator over this list, starting at a given index. The |
||||
* ListIterator returned by this method supports the add, remove and set |
||||
* methods. |
||||
* |
||||
* @param index the index of the element to be returned by the first call to |
||||
* next(), or size() to be initially positioned at the end of the list. |
||||
* @exception IndexOutOfBoundsException if index < 0 || index > size(). |
||||
*/ |
||||
public ListIterator listIterator(int index) { |
||||
|
||||
// Check bounds
|
||||
if (index < 0 || index > size) { |
||||
throw new IndexOutOfBoundsException(); |
||||
} |
||||
|
||||
return new Iter(back, getEntry(index, size, ends, ends), |
||||
index, size, modCount); |
||||
} |
||||
|
||||
/** |
||||
* Obtain a List view of a subsection of this list, from fromIndex |
||||
* (inclusive) to toIndex (exclusive). The returned list is modifiable in |
||||
* every respect. Changes to the returned list are reflected in this list. If |
||||
* this list is structurally modified is any way other than through the |
||||
* returned list, any subsequent operations on the returned list will result |
||||
* in a ConcurrentModificationException (that is, the returned list is |
||||
* fail-fast). |
||||
* |
||||
* @param fromIndex the index that the returned list should start from |
||||
* (inclusive). |
||||
* @param toIndex the index that the returned list should go to (exclusive). |
||||
* @returns a List backed by a subsection of this list. |
||||
* @exception IndexOutOfBoundsException if fromIndex < 0 || toIndex > size() |
||||
* || fromIndex > toIndex. |
||||
*/ |
||||
public List subList(int fromIndex, int toIndex) { |
||||
|
||||
// Check bounds
|
||||
if (fromIndex > toIndex || fromIndex < 0 || toIndex > size) { |
||||
throw new IndexOutOfBoundsException(); |
||||
} |
||||
|
||||
return new SubLinkedList(back, getEntry(fromIndex - 1, size, ends, ends), |
||||
getEntry(toIndex, size, ends, ends), |
||||
toIndex - fromIndex); |
||||
} |
||||
|
||||
private static class SubLinkedList extends AbstractSequentialList { |
||||
|
||||
Entry head; // entry before the beginning
|
||||
Entry tail; // entry after the end
|
||||
int size; |
||||
private final Backing b; |
||||
|
||||
private final Backing back = new Backing() { |
||||
public void checkMod(int known) { |
||||
if (known != modCount) { |
||||
throw new ConcurrentModificationException(); |
||||
} |
||||
} |
||||
public void upMod() { |
||||
modCount++; |
||||
} |
||||
public void incSize(int by) { |
||||
size += by; |
||||
} |
||||
public void decSize(int by) { |
||||
size -= by; |
||||
} |
||||
}; |
||||
|
||||
SubLinkedList(Backing backing, Entry h, Entry t, int s) { |
||||
b = backing; |
||||
head = h; |
||||
tail = t; |
||||
size = s; |
||||
} |
||||
|
||||
public int size() { |
||||
b.checkMod(this.modCount); |
||||
return size; |
||||
} |
||||
|
||||
public ListIterator listIterator(int index) { |
||||
b.checkMod(this.modCount); |
||||
|
||||
// Check bounds
|
||||
if (index < 0 || index > size) { |
||||
throw new IndexOutOfBoundsException(); |
||||
} |
||||
|
||||
return new Iter(back, getEntry(index, size, head, tail), |
||||
index, size, modCount); |
||||
} |
||||
|
||||
public void clear() { |
||||
b.checkMod(this.modCount); |
||||
head.next = tail; |
||||
tail.previous = head; |
||||
size = 0; |
||||
b.decSize(size); |
||||
modCount++; |
||||
b.upMod(); |
||||
} |
||||
|
||||
// No removeRange because this class cannot be publically subclassed.
|
||||
|
||||
public List subList(int fromIndex, int toIndex) { |
||||
b.checkMod(this.modCount); |
||||
|
||||
// Check bounds
|
||||
if (fromIndex > toIndex || fromIndex < 0 || toIndex > size) { |
||||
throw new IndexOutOfBoundsException(); |
||||
} |
||||
|
||||
return new SubLinkedList(back, getEntry(fromIndex - 1, size, head, tail), |
||||
getEntry(toIndex, size, head, tail), |
||||
toIndex - fromIndex); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Create a shallow copy of this LinkedList. |
||||
* @return an object of the same class as this object, containing the |
||||
* same elements in the same order. |
||||
*/ |
||||
public Object clone() |
||||
{ |
||||
LinkedList copy; |
||||
try |
||||
{ |
||||
copy = (LinkedList) super.clone(); |
||||
} |
||||
catch (CloneNotSupportedException ex) |
||||
{ |
||||
throw new InternalError(ex.getMessage()); |
||||
} |
||||
copy.size = 0; |
||||
copy.ends = new Entry(); |
||||
copy.addAll(this); |
||||
return copy; |
||||
} |
||||
|
||||
/** |
||||
* Serialize an object to a stream. |
||||
* @serialdata the size of the list (int), followed by all the elements |
||||
* (Object) in proper order. |
||||
*/ |
||||
private void writeObject(ObjectOutputStream s) |
||||
throws IOException |
||||
{ |
||||
s.writeInt(size); |
||||
for (Iterator i = iterator(); i.hasNext(); ) |
||||
s.writeObject(i.next()); |
||||
} |
||||
|
||||
/** |
||||
* Deserialize an object from a stream. |
||||
* @serialdata the size of the list (int), followed by all the elements |
||||
* (Object) in proper order. |
||||
*/ |
||||
private void readObject(ObjectInputStream s) |
||||
throws IOException, ClassNotFoundException |
||||
{ |
||||
int serialSize = s.readInt(); |
||||
ends = new Entry(); |
||||
for (int i=0; i< serialSize; i++) |
||||
addLast(s.readObject()); |
||||
} |
||||
} |
@ -1,331 +0,0 @@ |
||||
// This interface is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// List.java -- An ordered collection which allows indexed access
|
||||
//
|
||||
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TO DO:
|
||||
// ~ Doc comment for the interface itself needs to be put into english.
|
||||
// ~ Some more @see clauses might be nice.
|
||||
|
||||
package jode.util; |
||||
|
||||
/** |
||||
* [This is what this doc comment will mention: |
||||
* ~ Additional restrictions on some methods. Others included for completeness. |
||||
* ~ ListIterator and what it can do |
||||
* ~ Positional and iterated access |
||||
* ~ search (but linear time) |
||||
* ~ be careful when containing self as an element, because equals and hashCode |
||||
* loop.] |
||||
*/ |
||||
public interface List extends Collection { |
||||
|
||||
/** |
||||
* Insert an element into the list at a given position. |
||||
* |
||||
* @param index the location to insert the item. |
||||
* @param o the object to insert. |
||||
* @exception UnsupportedOperationException if this list does not support the |
||||
* add operation. |
||||
* @exception IndexOutOfBoundsException if index < 0 || index > size() |
||||
* @exception ClassCastException if o cannot be added to this list due to its |
||||
* type. |
||||
* @exception IllegalArgumentException if o cannot be added to this list for |
||||
* some other reason. |
||||
*/ |
||||
void add(int index, Object o); |
||||
|
||||
/** |
||||
* Add an element to the end of the list. |
||||
* |
||||
* @param o the object to add. |
||||
* @returns true, as Collection defines this method as returning true if the |
||||
* list was modified as a result of this action, and it always is for a |
||||
* list. |
||||
* @exception UnsupportedOperationException if this list does not support the |
||||
* add operation. |
||||
* @exception ClassCastException if o cannot be added to this list due to its |
||||
* type. |
||||
* @exception IllegalArgumentException if o cannot be added to this list for |
||||
* some other reason. |
||||
*/ |
||||
boolean add(Object o); |
||||
|
||||
/** |
||||
* Insert the contents of a collection into the list at a given position. |
||||
* |
||||
* @param index the location to insert the collection. |
||||
* @param c the collection to insert. |
||||
* @returns true if the list was modified by this action, that is, if c is |
||||
* non-empty. |
||||
* @exception UnsupportedOperationException if this list does not support the |
||||
* addAll operation. |
||||
* @exception IndexOutOfBoundsException if index < 0 || index > size() |
||||
* @exception ClassCastException if some element of c cannot be added to this |
||||
* list due to its type. |
||||
* @exception IllegalArgumentException if some element of c cannot be added |
||||
* to this list for some other reason. |
||||
*/ |
||||
boolean addAll(int index, Collection c); |
||||
|
||||
/** |
||||
* Add the contents of a collection to the end of the list. |
||||
* |
||||
* @param c the collection to add. |
||||
* @returns true if the list was modified by this action, that is, if c is |
||||
* non-empty. |
||||
* @exception UnsupportedOperationException if this list does not support the |
||||
* addAll operation. |
||||
* @exception ClassCastException if some element of c cannot be added to this |
||||
* list due to its type. |
||||
* @exception IllegalArgumentException if some element of c cannot be added |
||||
* to this list for some other reason. |
||||
*/ |
||||
boolean addAll(Collection c); |
||||
|
||||
/** |
||||
* Clear the list, such that a subsequent call to isEmpty() would return |
||||
* true. |
||||
* |
||||
* @exception UnsupportedOperationException if this list does not support the |
||||
* clear operation. |
||||
*/ |
||||
void clear(); |
||||
|
||||
/** |
||||
* Test whether this list contains a given object as one of its elements. |
||||
* |
||||
* @param o the element to look for. |
||||
* @returns true if this list contains an element e such that <code>o == |
||||
* null ? e == null : o.equals(e)</code>. |
||||
*/ |
||||
boolean contains(Object o); |
||||
|
||||
/** |
||||
* Test whether this list contains every element in a given collection. |
||||
* |
||||
* @param c the collection to test for. |
||||
* @returns true if for every element o in c, contains(o) would return true. |
||||
*/ |
||||
boolean containsAll(Collection c); |
||||
|
||||
/** |
||||
* Test whether this list is equal to another object. A List is defined to be |
||||
* equal to an object if and only if that object is also a List, and the two |
||||
* lists are equal. Two lists l1 and l2 are defined to be equal if and only |
||||
* if <code>l1.size() == l2.size()</code>, and for every integer n between 0 |
||||
* and <code>l1.size() - 1</code> inclusive, <code>l1.get(n) == null ? |
||||
* l2.get(n) == null : l1.get(n).equals(l2.get(n))</code>. |
||||
* |
||||
* @param o the object to test for equality with this list. |
||||
* @returns true if o is equal to this list. |
||||
*/ |
||||
boolean equals(Object o); |
||||
|
||||
/** |
||||
* Get the element at a given index in this list. |
||||
* |
||||
* @param index the index of the element to be returned. |
||||
* @returns the element at index index in this list. |
||||
* @exception IndexOutOfBoundsException if index < 0 || index >= size() |
||||
*/ |
||||
Object get(int index); |
||||
|
||||
/** |
||||
* Obtain a hash code for this list. In order to obey the general contract of |
||||
* the hashCode method of class Object, this value is calculated as follows: |
||||
* <pre> |
||||
* hashCode = 1; |
||||
* Iterator i = list.iterator(); |
||||
* while (i.hasNext()) { |
||||
* Object obj = i.next(); |
||||
* hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode()); |
||||
* } |
||||
* </pre> |
||||
* This ensures that the general contract of Object.hashCode() is adhered to. |
||||
* |
||||
* @returns the hash code of this list. |
||||
*/ |
||||
int hashCode(); |
||||
|
||||
/** |
||||
* Obtain the first index at which a given object is to be found in this |
||||
* list. |
||||
* |
||||
* @returns the least integer n such that <code>o == null ? get(n) == null : |
||||
* o.equals(get(n))</code>, or -1 if there is no such index. |
||||
*/ |
||||
int indexOf(Object o); |
||||
|
||||
/** |
||||
* Test whether this list is empty, that is, if size() == 0. |
||||
* |
||||
* @returns true if this list contains no elements. |
||||
*/ |
||||
boolean isEmpty(); |
||||
|
||||
/** |
||||
* Obtain an Iterator over this list. |
||||
* |
||||
* @returns an Iterator over the elements of this list, in order. |
||||
*/ |
||||
Iterator iterator(); |
||||
|
||||
/** |
||||
* Obtain the last index at which a given object is to be found in this |
||||
* list. |
||||
* |
||||
* @returns the greatest integer n such that <code>o == null ? get(n) == null |
||||
* : o.equals(get(n))</code>. |
||||
*/ |
||||
int lastIndexOf(Object o); |
||||
|
||||
/** |
||||
* Obtain a ListIterator over this list, starting at the beginning. |
||||
* |
||||
* @returns a ListIterator over the elements of this list, in order, starting |
||||
* at the beginning. |
||||
*/ |
||||
ListIterator listIterator(); |
||||
|
||||
/** |
||||
* Obtain a ListIterator over this list, starting at a given position. |
||||
* |
||||
* @param index the position, between 0 and size() inclusive, to begin the |
||||
* iteration from. |
||||
* @returns a ListIterator over the elements of this list, in order, starting |
||||
* at index. |
||||
* @exception IndexOutOfBoundsException if index < 0 || index > size() |
||||
*/ |
||||
ListIterator listIterator(int index); |
||||
|
||||
/** |
||||
* Remove the element at a given position in this list. |
||||
* |
||||
* @param index the position within the list of the object to remove. |
||||
* @returns the object that was removed. |
||||
* @exception UnsupportedOperationException if this list does not support the |
||||
* remove operation. |
||||
* @exception IndexOutOfBoundsException if index < 0 || index > size() |
||||
*/ |
||||
Object remove(int index); |
||||
|
||||
/** |
||||
* Remove the first occurence of an object from this list. That is, remove |
||||
* the first element e such that <code>o == null ? e == null : |
||||
* o.equals(e)</code>. |
||||
* |
||||
* @param o the object to remove. |
||||
* @returns true if the list changed as a result of this call, that is, if |
||||
* the list contained at least one occurrence of o. |
||||
* @exception UnsupportedOperationException if this list does not support the |
||||
* remove operation. |
||||
*/ |
||||
boolean remove(Object o); |
||||
|
||||
/** |
||||
* Remove all elements of a given collection from this list. That is, remove |
||||
* every element e such that c.contains(e). |
||||
* |
||||
* @returns true if this list was modified as a result of this call. |
||||
* @exception UnsupportedOperationException if this list does not support the |
||||
* removeAll operation. |
||||
*/ |
||||
boolean removeAll(Collection c); |
||||
|
||||
/** |
||||
* Remove all elements of this list that are not contained in a given |
||||
* collection. That is, remove every element e such that !c.contains(e). |
||||
* |
||||
* @returns true if this list was modified as a result of this call. |
||||
* @exception UnsupportedOperationException if this list does not support the |
||||
* retainAll operation. |
||||
*/ |
||||
boolean retainAll(Collection c); |
||||
|
||||
/** |
||||
* Replace an element of this list with another object. |
||||
* |
||||
* @param index the position within this list of the element to be replaced. |
||||
* @param o the object to replace it with. |
||||
* @returns the object that was replaced. |
||||
* @exception UnsupportedOperationException if this list does not support the |
||||
* set operation. |
||||
* @exception IndexOutOfBoundsException if index < 0 || index >= size() |
||||
* @exception ClassCastException if o cannot be added to this list due to its |
||||
* type. |
||||
* @exception IllegalArgumentException if o cannot be added to this list for |
||||
* some other reason. |
||||
*/ |
||||
Object set(int index, Object o); |
||||
|
||||
/** |
||||
* Get the number of elements in this list. |
||||
* |
||||
* @returns the number of elements in the list. |
||||
*/ |
||||
int size(); |
||||
|
||||
/** |
||||
* Obtain a List view of a subsection of this list, from fromIndex |
||||
* (inclusive) to toIndex (exclusive). The returned list should be modifiable |
||||
* if and only if this list is modifiable. Changes to the returned list |
||||
* should be reflected in this list. If this list is structurally modified in |
||||
* any way other than through the returned list, the result of any subsequent |
||||
* operations on the returned list is undefined. |
||||
* |
||||
* @param fromIndex the index that the returned list should start from |
||||
* (inclusive). |
||||
* @param toIndex the index that the returned list should go to (exclusive). |
||||
* @returns a List backed by a subsection of this list. |
||||
* @exception IndexOutOfBoundsException if fromIndex < 0 || toIndex > size() |
||||
* || fromIndex > toIndex. |
||||
*/ |
||||
List subList(int fromIndex, int toIndex); |
||||
|
||||
/** |
||||
* Copy the current contents of this list into an array. |
||||
* |
||||
* @returns an array of type Object[] and length equal to the length of this |
||||
* list, containing the elements currently in this list, in order. |
||||
*/ |
||||
Object[] toArray(); |
||||
|
||||
/** |
||||
* Copy the current contents of this list into an array. If the array passed |
||||
* as an argument has length less than that of this list, an array of the |
||||
* same run-time type as a, and length equal to the length of this list, is |
||||
* allocated using Reflection. Otherwise, a itself is used. The elements of |
||||
* this list are copied into it, and if there is space in the array, the |
||||
* following element is set to null. The resultant array is returned. |
||||
* Note: The fact that the following element is set to null is only useful |
||||
* if it is known that this list does not contain any null elements. |
||||
* |
||||
* @param a the array to copy this list into. |
||||
* @returns an array containing the elements currently in this list, in |
||||
* order. |
||||
* @exception ArrayStoreException if the type of any element of the |
||||
* collection is not a subtype of the element type of a. |
||||
*/ |
||||
Object[] toArray(Object[] a); |
||||
} |
@ -1,145 +0,0 @@ |
||||
// This interface is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// ListIterator.java -- Extended Iterator for iterating over ordered lists
|
||||
//
|
||||
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package jode.util; |
||||
|
||||
/** |
||||
* An extended version of Iterator to support the extra features of Lists. The |
||||
* elements may be accessed in forward or reverse order, elements may be |
||||
* replaced as well as removed, and new elements may be inserted, during the |
||||
* traversal of the list. |
||||
*/ |
||||
public interface ListIterator extends Iterator { |
||||
|
||||
/** |
||||
* Tests whether there are elements remaining in the list in the forward |
||||
* direction. |
||||
* |
||||
* @return true if there is at least one more element in the list in the |
||||
* forward direction, that is, if the next call to next will not throw |
||||
* NoSuchElementException. |
||||
*/ |
||||
boolean hasNext(); |
||||
|
||||
/** |
||||
* Tests whether there are elements remaining in the list in the reverse |
||||
* direction. |
||||
* |
||||
* @return true if there is at least one more element in the list in the |
||||
* reverse direction, that is, if the next call to previous will not throw |
||||
* NoSuchElementException. |
||||
*/ |
||||
boolean hasPrevious(); |
||||
|
||||
/** |
||||
* Obtain the next element in the list in the forward direction. Repeated |
||||
* calls to next may be used to iterate over the entire list, or calls to next |
||||
* and previous may be used together to go forwards and backwards. Alternating |
||||
* calls to next and previous will return the same element. |
||||
* |
||||
* @return the next element in the list in the forward direction |
||||
* @exception NoSuchElementException if there are no more elements |
||||
*/ |
||||
Object next(); |
||||
|
||||
/** |
||||
* Obtain the next element in the list in the reverse direction. Repeated |
||||
* calls to previous may be used to iterate backwards over the entire list, or |
||||
* calls to next and previous may be used together to go forwards and |
||||
* backwards. Alternating calls to next and previous will return the same |
||||
* element. |
||||
* |
||||
* @return the next element in the list in the reverse direction |
||||
* @exception NoSuchElementException if there are no more elements |
||||
*/ |
||||
Object previous(); |
||||
|
||||
/** |
||||
* Find the index of the element that would be returned by a call to next. |
||||
* |
||||
* @return the index of the element that would be returned by a call to next, |
||||
* or list.size() if the iterator is at the end of the list. |
||||
*/ |
||||
int nextIndex(); |
||||
|
||||
/** |
||||
* Find the index of the element that would be returned by a call to previous. |
||||
* |
||||
* @return the index of the element that would be returned by a call to |
||||
* previous, or -1 if the iterator is at the beginning of the list. |
||||
*/ |
||||
int previousIndex(); |
||||
|
||||
/** |
||||
* Insert an element into the list at the current position of the iterator. |
||||
* The element is inserted in between the element that would be returned by |
||||
* previous and the element that would be returned by next. After the |
||||
* insertion, a subsequent call to next is unaffected, but a call to |
||||
* previous returns the item that was added. This operation is optional, it |
||||
* may throw an UnsupportedOperationException. |
||||
* |
||||
* @param o the object to insert into the list |
||||
* @exception ClassCastException the object is of a type which cannot be added |
||||
* to this list |
||||
* @exception IllegalArgumentException some other aspect of the object stops |
||||
* it being added to this list |
||||
* @exception UnsupportedOperationException if this ListIterator does not |
||||
* support the add operation |
||||
*/ |
||||
void add(Object o); |
||||
|
||||
/** |
||||
* Remove from the list the element last returned by a call to next or |
||||
* previous. This method may only be called if neither add nor remove have |
||||
* been called since the last call to next or previous. This operation is |
||||
* optional, it may throw an UnsupportedOperationException. |
||||
* |
||||
* @exception IllegalStateException if neither next or previous have been |
||||
* called, or if add or remove has been called since the last call to next |
||||
* or previous. |
||||
* @exception UnsupportedOperationException if this ListIterator does not |
||||
* support the remove operation. |
||||
*/ |
||||
void remove(); |
||||
|
||||
/** |
||||
* Replace the element last returned by a call to next or previous with a |
||||
* given object. This method may only be called if neither add nor remove have |
||||
* been called since the last call to next or previous. This operation is |
||||
* optional, it may throw an UnsupportedOperationException. |
||||
* |
||||
* @param o the object to replace the element with |
||||
* @exception ClassCastException the object is of a type which cannot be added |
||||
* to this list |
||||
* @exception IllegalArgumentException some other aspect of the object stops |
||||
* it being added to this list |
||||
* @exception IllegalStateException if neither next or previous have been |
||||
* called, or if add or remove has been called since the last call to next |
||||
* or previous. |
||||
* @exception UnsupportedOperationException if this ListIterator does not |
||||
* support the set operation. |
||||
*/ |
||||
void set(Object o); |
||||
} |
@ -1,55 +0,0 @@ |
||||
// This interface is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Map.java -- An object that maps keys to values
|
||||
//
|
||||
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TO DO:
|
||||
// ~ Doc comments for everything.
|
||||
|
||||
package jode.util; |
||||
|
||||
public interface Map |
||||
{ |
||||
public void clear(); |
||||
public boolean containsKey(Object key); |
||||
public boolean containsValue(Object value); |
||||
public Set entrySet(); |
||||
public boolean equals(Object o); |
||||
public Object get(Object key); |
||||
public Object put(Object key, Object value); |
||||
public int hashCode(); |
||||
public boolean isEmpty(); |
||||
public Set keySet(); |
||||
public void putAll(Map m); |
||||
public Object remove(Object o); |
||||
public int size(); |
||||
public Collection values(); |
||||
|
||||
public static interface Entry { |
||||
public Object getKey(); |
||||
public Object getValue(); |
||||
public Object setValue(Object value); |
||||
public int hashCode(); |
||||
public boolean equals(Object o); |
||||
} |
||||
} |
@ -1,46 +0,0 @@ |
||||
// This interface is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Set.java -- A collection that prohibits duplicates
|
||||
//
|
||||
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TO DO:
|
||||
// ~ Doc comments for everything.
|
||||
|
||||
package jode.util; |
||||
|
||||
public interface Set extends Collection { |
||||
boolean add(Object o); |
||||
boolean addAll(Collection c); |
||||
void clear(); |
||||
boolean contains(Object o); |
||||
boolean containsAll(Collection c); |
||||
boolean equals(Object o); |
||||
int hashCode(); |
||||
boolean isEmpty(); |
||||
Iterator iterator(); |
||||
boolean remove(Object o); |
||||
boolean removeAll(Collection c); |
||||
boolean retainAll(Collection c); |
||||
int size(); |
||||
Object[] toArray(); |
||||
} |
@ -1,38 +0,0 @@ |
||||
// This interface is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// SortedMap.java -- A map that makes guarantees about the order of its keys
|
||||
//
|
||||
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TO DO:
|
||||
// ~ Doc comments for everything.
|
||||
|
||||
package jode.util; |
||||
|
||||
public interface SortedMap extends Map { |
||||
Comparator comparator(); |
||||
Object firstKey(); |
||||
SortedMap headMap(Object toKey); |
||||
Object lastKey(); |
||||
SortedMap subMap(Object fromKey, Object toKey); |
||||
SortedMap tailMap(Object fromKey); |
||||
} |
@ -1,38 +0,0 @@ |
||||
// This interface is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// SortedSet.java -- A set that makes guarantees about the order of its elements
|
||||
//
|
||||
// Copyright (c) 1998 by Stuart Ballard (stuart.ballard@mcmail.com)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TO DO:
|
||||
// ~ Doc comments for everything.
|
||||
|
||||
package jode.util; |
||||
|
||||
public interface SortedSet extends Set { |
||||
Comparator comparator(); |
||||
Object first(); |
||||
SortedSet headSet(Object toElement); |
||||
Object last(); |
||||
SortedSet subSet(Object fromElement, Object toElement); |
||||
SortedSet tailSet(Object fromElement); |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -1,331 +0,0 @@ |
||||
// This class is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// TreeSet.java -- a class providing a TreeMap-backet SortedSet
|
||||
//
|
||||
// Copyright (c) 1999 by Jon A. Zeppieri (jon@eease.com)
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Library General Public License as published
|
||||
// by the Free Software Foundation, version 2. (see COPYING.LIB)
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public License
|
||||
// along with this program; if not, write to the Free Software Foundation
|
||||
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
package jode.util; |
||||
|
||||
import java.io.IOException; |
||||
import java.io.Serializable; |
||||
import java.io.ObjectInputStream; |
||||
import java.io.ObjectOutputStream; |
||||
|
||||
/** |
||||
* This class provides a TreeMap-backed implementation of the |
||||
* SortedSet interface. |
||||
* |
||||
* Each element in the Set is a key in the backing TreeMap; each key |
||||
* maps to a static token, denoting that the key does, in fact, exist. |
||||
* |
||||
* Most operations are O(log n). |
||||
* |
||||
* TreeSet is a part of the JDK1.2 Collections API. |
||||
* |
||||
* @author Jon Zeppieri |
||||
* @version $Revision$ |
||||
* @modified $Id$ |
||||
*/ |
||||
|
||||
public class TreeSet extends AbstractSet |
||||
implements SortedSet, Cloneable, Serializable |
||||
{ |
||||
// INSTANCE VARIABLES -------------------------------------------------
|
||||
|
||||
/** The TreeMap which backs this Set */ |
||||
transient SortedMap _oMap; |
||||
static final long serialVersionUID = -2479143000061671589L; |
||||
|
||||
|
||||
// CONSTRUCTORS -------------------------------------------------------
|
||||
|
||||
/** |
||||
* Construct a new TreeSet whose backing TreeMap using the "natural" ordering |
||||
* of keys. |
||||
*/ |
||||
public TreeSet() |
||||
{ |
||||
this((Comparator) null); |
||||
} |
||||
|
||||
/** |
||||
* Construct a new TreeSet whose backing TreeMap uses the supplied |
||||
* Comparator. |
||||
* |
||||
* @param oComparator the Comparator this Set will use |
||||
*/ |
||||
public TreeSet(Comparator oComparator) |
||||
{ |
||||
_oMap = new TreeMap(oComparator); |
||||
} |
||||
|
||||
/** |
||||
* Construct a new TreeSet whose backing TreeMap uses the "natural" |
||||
* orering of the keys and which contains all of the elements in the |
||||
* supplied Collection. |
||||
* |
||||
* @param oCollection the new Set will be initialized with all |
||||
* of the elements in this Collection |
||||
*/ |
||||
public TreeSet(Collection oCollection) |
||||
{ |
||||
this((Comparator) null); |
||||
addAll(oCollection); |
||||
} |
||||
|
||||
/** |
||||
* Construct a new TreeSet, using the same key ordering as the supplied |
||||
* SortedSet and containing all of the elements in the supplied SortedSet. |
||||
* This constructor runs in linear time. |
||||
* |
||||
* @param oSortedSet the new TreeSet will use this SortedSet's |
||||
* comparator and will initialize itself |
||||
* with all of the elements in this SortedSet |
||||
*/ |
||||
public TreeSet(SortedSet oSortedSet) |
||||
{ |
||||
this(oSortedSet.comparator()); |
||||
|
||||
TreeMap oMap = (TreeMap) _oMap; |
||||
int i = 0; |
||||
Map.Entry[] arEntries = new Map.Entry[oSortedSet.size()]; |
||||
Iterator itEntries = oSortedSet.iterator(); |
||||
|
||||
while (itEntries.hasNext()) |
||||
arEntries[i++] = new BasicMapEntry(itEntries.next(), Boolean.TRUE); |
||||
|
||||
oMap._iSize = i; |
||||
oMap.putAllLinear(arEntries); |
||||
} |
||||
|
||||
TreeSet(SortedMap oMap) |
||||
{ |
||||
_oMap = oMap; |
||||
} |
||||
|
||||
// METHODS -----------------------------------------------------------
|
||||
|
||||
/** |
||||
* Adds the spplied Object to the Set if it is not already in the Set; |
||||
* returns true if the element is added, false otherwise |
||||
* |
||||
* @param oObject the Object to be added to this Set |
||||
*/ |
||||
public boolean add(Object oObject) |
||||
{ |
||||
if (_oMap.containsKey(oObject)) |
||||
{ |
||||
return false; |
||||
} |
||||
else |
||||
{ |
||||
internalAdd(_oMap, oObject); |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Adds all of the elements in the supplied Collection to this TreeSet. |
||||
* |
||||
* @param oCollection All of the elements in this Collection |
||||
* will be added to the Set. |
||||
* |
||||
* @return true if the Set is altered, false otherwise |
||||
*/ |
||||
public boolean addAll(Collection oCollection) |
||||
{ |
||||
boolean boResult = false; |
||||
Iterator itElements = oCollection.iterator(); |
||||
|
||||
while (itElements.hasNext()) |
||||
boResult = (boResult || add(itElements.next())); |
||||
|
||||
return boResult; |
||||
} |
||||
|
||||
/** |
||||
* Removes all elements in this Set. |
||||
*/ |
||||
public void clear() |
||||
{ |
||||
_oMap.clear(); |
||||
} |
||||
|
||||
/** Returns a shallow copy of this Set. */ |
||||
public Object clone() |
||||
{ |
||||
TreeSet oClone; |
||||
|
||||
try |
||||
{ |
||||
oClone = (TreeSet) super.clone(); |
||||
oClone._oMap = _oMap; |
||||
} |
||||
catch(CloneNotSupportedException e) |
||||
{ |
||||
oClone = null; |
||||
} |
||||
return oClone; |
||||
} |
||||
|
||||
/** Returns this Set's comparator */ |
||||
public Comparator comparator() |
||||
{ |
||||
return _oMap.comparator(); |
||||
} |
||||
|
||||
/** |
||||
* Returns true if this Set contains the supplied Object, |
||||
* false otherwise |
||||
* |
||||
* @param oObject the Object whose existence in the Set is |
||||
* being tested |
||||
*/ |
||||
public boolean contains(Object oObject) |
||||
{ |
||||
return _oMap.containsKey(oObject); |
||||
} |
||||
|
||||
/** Returns true if this Set has size 0, false otherwise */ |
||||
public boolean isEmpty() |
||||
{ |
||||
return _oMap.isEmpty(); |
||||
} |
||||
|
||||
/** Returns the number of elements in this Set */ |
||||
public int size() |
||||
{ |
||||
return _oMap.size(); |
||||
} |
||||
|
||||
/** |
||||
* If the supplied Object is in this Set, it is removed, and true is |
||||
* returned; otherwise, false is returned. |
||||
* |
||||
* @param oObject the Object we are attempting to remove |
||||
* from this Set |
||||
*/ |
||||
public boolean remove(Object oObject) |
||||
{ |
||||
return (_oMap.remove(oObject) != null); |
||||
} |
||||
|
||||
/** Returns the first (by order) element in this Set */ |
||||
public Object first() |
||||
{ |
||||
return _oMap.firstKey(); |
||||
} |
||||
|
||||
/** Returns the last (by order) element in this Set */ |
||||
public Object last() |
||||
{ |
||||
return _oMap.lastKey(); |
||||
} |
||||
|
||||
/** |
||||
* Returns a view of this Set including all elements in the interval |
||||
* [oFromElement, oToElement). |
||||
* |
||||
* @param oFromElement the resultant view will contain all |
||||
* elements greater than or equal to this |
||||
* element |
||||
* @param oToElement the resultant view will contain all |
||||
* elements less than this element |
||||
*/ |
||||
public SortedSet subSet(Object oFromElement, Object oToElement) |
||||
{ |
||||
return new TreeSet(_oMap.subMap(oFromElement, oToElement)); |
||||
} |
||||
|
||||
/** |
||||
* Returns a view of this Set including all elements less than oToElement |
||||
* |
||||
* @param oToElement the resultant view will contain all |
||||
* elements less than this element |
||||
*/ |
||||
public SortedSet headSet(Object oToElement) |
||||
{ |
||||
return new TreeSet(_oMap.headMap(oToElement)); |
||||
} |
||||
|
||||
/** |
||||
* Returns a view of this Set including all elements greater than or |
||||
* equal to oFromElement. |
||||
* |
||||
* @param oFromElement the resultant view will contain all |
||||
* elements greater than or equal to this |
||||
* element |
||||
*/ |
||||
public SortedSet tailSet(Object oFromElement) |
||||
{ |
||||
return new TreeSet(_oMap.tailMap(oFromElement)); |
||||
} |
||||
|
||||
|
||||
/** Returns in Iterator over the elements in this TreeSet */ |
||||
public Iterator iterator() |
||||
{ |
||||
return _oMap.keySet().iterator(); |
||||
} |
||||
|
||||
private void writeObject(ObjectOutputStream oOut) throws IOException |
||||
{ |
||||
Iterator itElements = iterator(); |
||||
|
||||
oOut.writeObject(comparator()); |
||||
oOut.writeInt(size()); |
||||
|
||||
while (itElements.hasNext()) |
||||
oOut.writeObject(itElements.next()); |
||||
} |
||||
|
||||
private void readObject(ObjectInputStream oIn) |
||||
throws IOException, ClassNotFoundException |
||||
{ |
||||
int i; |
||||
Map.Entry[] arEntries; |
||||
TreeMap oMap; |
||||
Comparator oComparator = (Comparator) oIn.readObject(); |
||||
int iSize = oIn.readInt(); |
||||
|
||||
arEntries = new Map.Entry[iSize]; |
||||
|
||||
for (i = 0; i < iSize; i++) |
||||
arEntries[iSize] = new BasicMapEntry(oIn.readObject(), Boolean.TRUE); |
||||
|
||||
oMap = new TreeMap(oComparator); |
||||
oMap._iSize = iSize; |
||||
oMap.putAllLinear(arEntries); |
||||
_oMap = oMap; |
||||
} |
||||
|
||||
/** |
||||
* adds the supplied element to this Set; this private method is used |
||||
* internally instead of add(), because add() can be overridden |
||||
* to do unexpected things |
||||
* |
||||
* @param o the Object to add to this Set |
||||
*/ |
||||
private static final void internalAdd(Map oMap, Object oObject) |
||||
{ |
||||
oMap.put(oObject, Boolean.TRUE); |
||||
} |
||||
} |
@ -1,54 +0,0 @@ |
||||
// This interface is taken from the Classpath project.
|
||||
// Please note the different copyright holder!
|
||||
// The changes I did is this comment, the package line, some
|
||||
// imports from java.util and some minor jdk12 -> jdk11 fixes.
|
||||
// -- Jochen Hoenicke <jochen@gnu.org>
|
||||
|
||||
/************************************************************************* |
||||
/* UnsupportedOperationException.java -- Exception thrown when an |
||||
/* unsupported operation is attempted on an object |
||||
/* |
||||
/* Copyright (c) 1998 by Free Software Foundation, Inc. |
||||
/* |
||||
/* This program is free software; you can redistribute it and/or modify |
||||
/* it under the terms of the GNU Library General Public License as published |
||||
/* by the Free Software Foundation, version 2. (see COPYING.LIB) |
||||
/* |
||||
/* This program is distributed in the hope that it will be useful, but |
||||
/* WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
/* GNU General Public License for more details. |
||||
/* |
||||
/* You should have received a copy of the GNU General Public License |
||||
/* along with this program; if not, write to the Free Software Foundation |
||||
/* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA |
||||
/*************************************************************************/ |
||||
|
||||
package jode.util; |
||||
|
||||
/** |
||||
* This exception is thrown by an object when an operation is |
||||
* requested of it that it does not support. |
||||
* |
||||
* @since JDK 1.2 |
||||
*/ |
||||
public class UnsupportedOperationException extends RuntimeException |
||||
{ |
||||
static final long serialVersionUID = -1242599979055084673L; |
||||
|
||||
/** |
||||
* Create an exception without a message. |
||||
*/ |
||||
public UnsupportedOperationException() |
||||
{ |
||||
super(); |
||||
} |
||||
|
||||
/** |
||||
* Create an exception with a message. |
||||
*/ |
||||
public UnsupportedOperationException( String s ) |
||||
{ |
||||
super(s); |
||||
} |
||||
} |
Loading…
Reference in new issue