一、前言
关于flink-core源码包中通过org.apache.flink.api.common.operators.util.FieldSet、org.apache.flink.api.common.operators.util.FieldList自定义类集、序列,具体见源码说明。
二、源码说明
1.FieldSet类
package org.apache.flink.api.common.operators.util;@b@@b@import org.apache.flink.annotation.Internal;@b@@b@import java.util.Arrays;@b@import java.util.Collection;@b@import java.util.Collections;@b@import java.util.HashSet;@b@import java.util.Iterator;@b@@b@/**@b@ * Immutable unordered collection of fields IDs.@b@ */@b@@Internal@b@public class FieldSet implements Iterable<Integer> {@b@ @b@ public static final FieldSet EMPTY_SET = new FieldSet();@b@ @b@ protected final Collection<Integer> collection;@b@@b@ // --------------------------------------------------------------------------------------------@b@@b@ /**@b@ * Creates a new empty set of fields.@b@ */@b@ public FieldSet() {@b@ this.collection = Collections.emptySet();@b@ }@b@ @b@ /**@b@ * Creates a set with one field.@b@ * @b@ * @param fieldID The id of the field.@b@ */@b@ public FieldSet(Integer fieldID) {@b@ if (fieldID == null) {@b@ throw new IllegalArgumentException("Field ID must not be null.");@b@ }@b@ @b@ this.collection = Collections.singleton(fieldID);@b@ }@b@ @b@ /**@b@ * Creates a set with the given fields.@b@ * @b@ * @param fieldIDs The IDs of the fields.@b@ */@b@ public FieldSet(int... fieldIDs) {@b@ if (fieldIDs == null || fieldIDs.length == 0) {@b@ this.collection = Collections.emptySet();@b@ } else {@b@ HashSet<Integer> set = new HashSet<Integer>(2 * fieldIDs.length);@b@ for (int i = 0; i < fieldIDs.length; i++) {@b@ set.add(fieldIDs[i]);@b@ }@b@ @b@ this.collection = Collections.unmodifiableSet(set);@b@ }@b@ }@b@ @b@ /**@b@ * Creates a set with the given fields.@b@ * @b@ * @param fieldIDs The IDs of the fields.@b@ */@b@ public FieldSet(int[] fieldIDs, boolean marker) {@b@ if (fieldIDs == null || fieldIDs.length == 0) {@b@ this.collection = Collections.emptySet();@b@ } else {@b@ HashSet<Integer> set = new HashSet<Integer>(2 * fieldIDs.length);@b@ for (int i = 0; i < fieldIDs.length; i++) {@b@ set.add(fieldIDs[i]);@b@ }@b@ @b@ this.collection = Collections.unmodifiableSet(set);@b@ }@b@ }@b@ @b@ protected FieldSet(Collection<Integer> fields) {@b@ this.collection = fields;@b@ }@b@ @b@ /**@b@ * @param fieldSet The first part of the new set, NOT NULL!@b@ * @param fieldID The ID to be added, NOT NULL!@b@ */@b@ private FieldSet(FieldSet fieldSet, Integer fieldID) {@b@ if (fieldSet.size() == 0) {@b@ this.collection = Collections.singleton(fieldID);@b@ }@b@ else {@b@ HashSet<Integer> set = new HashSet<Integer>(2 * (fieldSet.collection.size() + 1));@b@ set.addAll(fieldSet.collection);@b@ set.add(fieldID);@b@ this.collection = Collections.unmodifiableSet(set);@b@ }@b@ }@b@ @b@ private FieldSet(FieldSet fieldSet, int... fieldIDs) {@b@ if (fieldIDs == null || fieldIDs.length == 0) {@b@ this.collection = fieldSet.collection;@b@ } else {@b@ HashSet<Integer> set = new HashSet<Integer>(2 * (fieldSet.collection.size() + fieldIDs.length));@b@ set.addAll(fieldSet.collection);@b@ @b@ for (int i = 0; i < fieldIDs.length; i++) {@b@ set.add(fieldIDs[i]);@b@ }@b@ @b@ this.collection = Collections.unmodifiableSet(set);@b@ }@b@ }@b@ @b@ private FieldSet(FieldSet fieldSet1, FieldSet fieldSet2) {@b@ if (fieldSet2.size() == 0) {@b@ this.collection = fieldSet1.collection;@b@ }@b@ else if (fieldSet1.size() == 0) {@b@ this.collection = fieldSet2.collection;@b@ }@b@ else {@b@ HashSet<Integer> set = new HashSet<Integer>(2 * (fieldSet1.size() + fieldSet2.size()));@b@ set.addAll(fieldSet1.collection);@b@ set.addAll(fieldSet2.collection);@b@ this.collection = Collections.unmodifiableSet(set);@b@ }@b@ }@b@ @b@ // --------------------------------------------------------------------------------------------@b@ @b@ public FieldSet addField(Integer fieldID) {@b@ if (fieldID == null) {@b@ throw new IllegalArgumentException("Field ID must not be null.");@b@ }@b@ return new FieldSet(this, fieldID);@b@ }@b@@b@ public FieldSet addFields(int... fieldIDs) {@b@ return new FieldSet(this, fieldIDs);@b@ }@b@ @b@ public FieldSet addFields(FieldSet set) {@b@ if (set == null) {@b@ throw new IllegalArgumentException("FieldSet to add must not be null.");@b@ }@b@ @b@ if (set.size() == 0) {@b@ return this;@b@ }@b@ else if (this.size() == 0) {@b@ return set;@b@ }@b@ else {@b@ return new FieldSet(this, set);@b@ }@b@ }@b@ @b@ public boolean contains(Integer columnIndex) {@b@ return this.collection.contains(columnIndex);@b@ }@b@ @b@ public int size() {@b@ return this.collection.size();@b@ }@b@ @b@ @Override@b@ public Iterator<Integer> iterator() {@b@ return this.collection.iterator();@b@ }@b@ @b@ /**@b@ * Turns the FieldSet into an ordered FieldList.@b@ * @b@ * @return An ordered FieldList.@b@ */@b@ public FieldList toFieldList() {@b@ int[] pos = toArray();@b@ Arrays.sort(pos);@b@ return new FieldList(pos);@b@ }@b@ @b@ /**@b@ * Transforms the field set into an array of field IDs. Whether the IDs are ordered@b@ * or unordered depends on the specific subclass of the field set.@b@ * @b@ * @return An array of all contained field IDs.@b@ */@b@ public int[] toArray() {@b@ int[] a = new int[this.collection.size()];@b@ int i = 0;@b@ for (int col : this.collection) {@b@ a[i++] = col;@b@ }@b@ return a;@b@ }@b@ @b@ // --------------------------------------------------------------------------------------------@b@ @b@ /**@b@ * Checks if the given set of fields is a valid subset of this set of fields. For unordered@b@ * sets, this is the case if all of the given set's fields are also part of this field.@b@ * <p>@b@ * Subclasses that describe field sets where the field order matters must override this method@b@ * to implement a field ordering sensitive check.@b@ * @b@ * @param set The set that is a candidate subset.@b@ * @return True, if the given set is a subset of this set, false otherwise.@b@ */@b@ public boolean isValidSubset(FieldSet set) {@b@ if (set.size() > size()) {@b@ return false;@b@ }@b@ for (Integer i : set) {@b@ if (!contains(i)) {@b@ return false;@b@ }@b@ }@b@ return true;@b@ }@b@ @b@ // --------------------------------------------------------------------------------------------@b@ @b@ @Override@b@ public int hashCode() {@b@ return this.collection.hashCode();@b@ }@b@@b@ @Override@b@ public boolean equals(Object obj) {@b@ if (obj == null) {@b@ return false;@b@ }@b@ if (obj instanceof FieldSet) {@b@ return this.collection.equals(((FieldSet) obj).collection);@b@ } else {@b@ return false;@b@ }@b@ }@b@@b@@b@ @Override@b@ public String toString() {@b@ StringBuilder bld = new StringBuilder();@b@ bld.append(getDescriptionPrefix());@b@ for (Integer i : this.collection) {@b@ bld.append(i);@b@ bld.append(',');@b@ bld.append(' ');@b@ }@b@ if (this.collection.size() > 0) {@b@ bld.setLength(bld.length() - 2);@b@ }@b@ bld.append(getDescriptionSuffix());@b@ return bld.toString();@b@ }@b@ @b@@b@ /**@b@ * Since instances of FieldSet are strictly immutable, this method does not actually clone,@b@ * but it only returns the original instance.@b@ * @b@ * @return This objects reference, unmodified.@b@ */@b@ public FieldSet clone() {@b@ return this;@b@ }@b@ @b@ // --------------------------------------------------------------------------------------------@b@ @b@ protected String getDescriptionPrefix() {@b@ return "(";@b@ }@b@ @b@ protected String getDescriptionSuffix() {@b@ return ")";@b@ }@b@}
2.FieldList类
package org.apache.flink.api.common.operators.util;@b@@b@import org.apache.flink.annotation.Internal;@b@@b@import java.util.ArrayList;@b@import java.util.Collections;@b@import java.util.List;@b@@b@import static org.apache.flink.util.Preconditions.checkNotNull;@b@@b@/**@b@ * Immutable ordered list of fields IDs.@b@ */@b@@Internal@b@public class FieldList extends FieldSet {@b@ @b@ public static final FieldList EMPTY_LIST = new FieldList();@b@ @b@ @b@ public FieldList() {@b@ super(Collections.<Integer>emptyList());@b@ }@b@ @b@ public FieldList(int fieldId) {@b@ super(Collections.singletonList(fieldId));@b@ }@b@ @b@ public FieldList(Integer fieldId) {@b@ super(Collections.singletonList(checkNotNull(fieldId, "The fields ID must not be null.")));@b@ }@b@ @b@ public FieldList(int... columnIndexes) {@b@ super (fromInts(columnIndexes));@b@ }@b@ @b@ private FieldList(List<Integer> fields) {@b@ super(fields);@b@ }@b@ @b@ // --------------------------------------------------------------------------------------------@b@ @b@ @Override@b@ public FieldList addField(Integer fieldID) {@b@ if (fieldID == null) {@b@ throw new IllegalArgumentException("Field ID must not be null.");@b@ }@b@ @b@ if (size() == 0) {@b@ return new FieldList(fieldID);@b@ } else {@b@ ArrayList<Integer> list = new ArrayList<Integer>(size() + 1);@b@ list.addAll(this.collection);@b@ list.add(fieldID);@b@ return new FieldList(Collections.unmodifiableList(list));@b@ }@b@ }@b@@b@ @Override@b@ public FieldList addFields(int... fieldIDs) {@b@ if (fieldIDs == null || fieldIDs.length == 0) {@b@ return this;@b@ }@b@ if (size() == 0) {@b@ return new FieldList(fieldIDs);@b@ } else {@b@ ArrayList<Integer> list = new ArrayList<Integer>(size() + fieldIDs.length);@b@ list.addAll(this.collection);@b@ for (int i = 0; i < fieldIDs.length; i++) {@b@ list.add(fieldIDs[i]);@b@ }@b@ @b@ return new FieldList(Collections.unmodifiableList(list));@b@ }@b@ }@b@ @b@ @Override@b@ public FieldList addFields(FieldSet set) {@b@ if (set == null) {@b@ throw new IllegalArgumentException("FieldSet to add must not be null.");@b@ }@b@ @b@ if (set.size() == 0) {@b@ return this;@b@ }@b@ else if (size() == 0 && set instanceof FieldList) {@b@ return (FieldList) set;@b@ }@b@ else {@b@ ArrayList<Integer> list = new ArrayList<Integer>(size() + set.size());@b@ list.addAll(this.collection);@b@ list.addAll(set.collection);@b@ return new FieldList(Collections.unmodifiableList(list));@b@ }@b@ }@b@ @b@ public Integer get(int pos) {@b@ return get().get(pos);@b@ }@b@ @b@ @Override@b@ public FieldList toFieldList() {@b@ return this;@b@ }@b@@b@ // --------------------------------------------------------------------------------------------@b@ @b@ @Override@b@ public boolean isValidSubset(FieldSet set) {@b@ if (set instanceof FieldList) {@b@ return (isValidSubset((FieldList) set));@b@ } else {@b@ return false;@b@ }@b@ }@b@ @b@ public boolean isValidSubset(FieldList list) {@b@ if (list.size() > size()) {@b@ return false;@b@ }@b@ final List<Integer> myList = get();@b@ final List<Integer> theirList = list.get();@b@ for (int i = 0; i < theirList.size(); i++) {@b@ Integer myInt = myList.get(i);@b@ Integer theirInt = theirList.get(i);@b@ if (myInt.intValue() != theirInt.intValue()) {@b@ return false;@b@ }@b@ }@b@ return true;@b@ }@b@ @b@ public boolean isValidUnorderedPrefix(FieldSet set) {@b@ if (set.size() > size()) {@b@ return false;@b@ }@b@ @b@ List<Integer> list = get();@b@ for (int i = 0; i < set.size(); i++) {@b@ if (!set.contains(list.get(i))) {@b@ return false;@b@ }@b@ }@b@ return true;@b@ }@b@@b@ public boolean isExactMatch(FieldList list) {@b@ if (this.size() != list.size()) {@b@ return false;@b@ } else {@b@ for (int i = 0; i < this.size(); i++) {@b@ if (!this.get(i).equals(list.get(i))) {@b@ return false;@b@ }@b@ }@b@ return true;@b@ }@b@ }@b@ @b@ // --------------------------------------------------------------------------------------------@b@@b@ @Override@b@ protected String getDescriptionPrefix() {@b@ return "[";@b@ }@b@ @b@ @Override@b@ protected String getDescriptionSuffix() {@b@ return "]";@b@ }@b@@b@ private List<Integer> get() {@b@ return (List<Integer>) this.collection;@b@ }@b@ @b@ private static final List<Integer> fromInts(int... ints) {@b@ if (ints == null || ints.length == 0) {@b@ return Collections.emptyList();@b@ } else {@b@ ArrayList<Integer> al = new ArrayList<Integer>(ints.length);@b@ for (int i = 0; i < ints.length; i++) {@b@ al.add(ints[i]);@b@ }@b@ return Collections.unmodifiableList(al);@b@ }@b@ }@b@}