是否有一个比ArrayList更适合这种情况的集合?

时间:2018-01-17 15:08:05

标签: java arraylist

我有一个需要返回一组数据的方法,当前的计划是使用ArrayList的ArrayList,但我不确定是否有更合适的集合。​​

  • 该集合具有固定数量的行。它每个集合有n个组,它们将保持不变。
  • 该集合具有固定数量的数据条目。它们只是以未知的分布分布在集合的各行中。
  • 在输入数据处理完毕之前,我们不知道每一行的长度。

这种抽象的本质让我相信每一行最好用ArrayList表示,因为在最终将ArrayList添加到主ArrayList之前,可能会添加一些条目。

有没有更好的方法来做到这一点,特别是在性能方面?

3 个答案:

答案 0 :(得分:1)

如果行数是固定的(让我们说10)而不是列数,那么你可以使用一组列表,例如:

// Use whatever type you need instead of Integer.
@SuppressWarnings("unchecked")
List<Integer>[] arrayOfLists = new ArrayList[10];

此代码发出警告&#34;泛型数组创建&#34;。出于这个原因,我添加了@SuppressWarnings("unchecked")

答案 1 :(得分:1)

没有什么复杂的方法(但是由于直接访问数据而表现良好)如何拥有由groupKey(rowKey)表示的行和由comlunKey表示的colums的集合。在这里你可以添加可选对象。 简单来说就是地图图。

/**
 * representation of bi dimensional array with dynamical size
 *
 * @param <K> - type of row key
 * @param <L> - type of columne key
 * @param <V> - type of value
 */
public class CustomCollection<K, L, V> extends HashMap<K, Map<L, V>> {

public CustomCollection() {

}

/**
 * add new entry on particular row and column
 *
 * @param rowKey    - key of row
 * @param columnKey - key of column
 * @param value     - value to add
 */
public void addNewEntry(K rowKey, L columnKey, V value) {
    Map<L, V> columns = get(rowKey);
    if (columns == null) {
        columns = new HashMap<>();
        put(rowKey, columns);
    }
    columns.put(columnKey, value);
}

/**
 * get exact value on current row represented by {@code rowKey} and column represented by {@code columnKey}
 *
 * @param rowKey    - key of row
 * @param columnKey - key of column
 * @return
 */
public V getExactValue(K rowKey, V columnKey) {
    Map<L, V> columns = get(rowKey);
    if (columns == null) {
        return null;
    }
    return columns.get(columnKey);
}

/**
 * get colums values as map
 *
 * @param rowKey - key of row
 * @return
 */
public Map<L, V> getColumsAsMap(K rowKey) {
    return get(rowKey);
}

/**
 * get colums values as map
 *
 * @param rowKey - key of row
 * @return
 */
public Collection<V> getColumsAsCollection(K rowKey) {
    Map<L, V> columns = get(rowKey);
    if (columns == null) {
        return null;
    }
    return columns.values();
}

/**
 * remove value on particular index
 *
 * @param rowKey
 * @param columnKey
 *
 * @return - removed item
 */
public V removeExactValue(K rowKey, L columnKey){
    Map<L, V> columns = get(rowKey);
    if (columns == null) {
        return null;
    }
    return columns.remove(columnKey);
}

@Override
public String toString(){
    final StringBuffer stringBuffer = new StringBuffer();
    keySet().forEach(rowKey -> {
        stringBuffer.append(rowKey + " = {");
        Map<L, V> columns = get(rowKey);
        if (columns != null) {
            columns.entrySet().forEach(entry -> {
                stringBuffer.append("["+entry.getKey()+"="+entry.getValue()+"]");
            });
        }
        stringBuffer.append("}\n");
    });
    return stringBuffer.toString();
}
}

// Sample how to use it

public static void main(String [] args){
    CustomCollection<Integer,Integer,String> customCollection = new CustomCollection<>();
    customCollection.addNewEntry(1,1, "v_1_1");
    customCollection.addNewEntry(1,2,"v_1_2");
    customCollection.addNewEntry(2,1,"v_2_1");
    customCollection.addNewEntry(2,2,"v_2_2");
    customCollection.addNewEntry(2,3,"v_2_3");
    System.out.println(customCollection.toString());
    System.out.println("After remove:");
    customCollection.removeExactValue(2,2);
    customCollection.removeExactValue(2,3);
    System.out.println(customCollection.toString());
}

答案 2 :(得分:1)

在Java中,有 Jagged Arrays 的概念。它与你描述的基本相同。您可以通过两种方式之一实现它。

  1. 一个二维数组,您在声明变量时初始化行,并在需要使用时声明每一列。
  2. 一个Lists数组,在初始化时声明行,只需在需要时将行(列)添加到行中的每个索引。
  3. 2-D数组方法

    // Initialize the rows only for now
    String[][] arr = new String[3][];
    
    // Process some data to know the column sizes of each
    // ...
    arr[0] = new String[] {"Foo", "Bar", "FooBar"};
    arr[1] = new String[] {"Jane", "Doe"};
    arr[2] = new String[] {"Peter", "Parker", "Tony", "Stark"};
    // ...
    // Printing 
    for(String[] row : arr) {
        System.out.println(Arrays.ToString(row));
    }
    

    列表数组方法

    // Initialize the rows only for now
    List<String> [] arr = new List[3];
    
    // Process some data
    // ...
    List<String> list1 = new ArrayList<>();
    list1.add("Foo");
    list1.add("Bar");
    list1.add("FooBar");
    List<String> list2 = new ArrayList<>();
    list2.add("Jane");
    list2.add("Doe");
    List<String> list3 = new ArrayList<>();
    list3.add("Peter");
    list3.add("Parker");
    list3.add("Tony");
    list3.add("Stark");
    // ...
    // Printing
    for(int i = 0 ; i < arr.length; i++) {
        List<String> temp = arr[i];
        System.out.println(temp);
    }
    

    根据您的需求,因为您知道您的数据集始终保持不变。您只是不知道Jagged Array中每行的长度。基于此,Go采用简单的二维方法。

    现在,如果您认为要求将在以后发生变化,或者您喜欢ArrayLists拥有的有用方法(contains等),那么我会选择{{1 } Array

    除非数据集很大,否则您不会注意到两个实现之间的显着性能差异。如果遇到性能问题,请使用二维阵列方法。

    如果由我决定,我会采用ArrayLists Array方法。我会这样做因为:

      如果您的数据集发生变化,
    1. ArrayLists可以轻松扩展。
    2. ArrayLists还提供了许多有用的方法,这些方法更容易调用,然后必须自己实现。
    3. ArrayLists他们也实施了ArrayListsIterableCollection,因此可以在很多基于接口的API调用中使用。
    4. List可以执行的一些方法是here

      有关Jagged数组的更多信息,请here