简体   繁体   English

这是在Java中创建只读列表的方法吗?

[英]Is this an approach to create a read-only List in Java?

Thinking in java says: 用Java思考说:

To create a read-only List from AbstractList, you must implements get() and size(). 要从AbstractList创建只读列表,必须实现get()和size()。

It confused me, the code is below: 它让我感到困惑,代码如下:

 public class CountingIntegerList
extends AbstractList<Integer> {
  private int size;
  public CountingIntegerList(int size) {
    this.size = size < 0 ? 0 : size;
  }
  public Integer get(int index) {
    return Integer.valueOf(index);
  }
  public int size() { return size; }
  public static void main(String[] args) {
    List list = new CountingIntegerList(30);
  }
}

Is list a read-only List? 列表是只读列表吗? Why? 为什么?

Ok, the answer is yes since I extend AbstractList and it throw UnsupportedOperationException if set or and is called. 好的,答案是肯定的,因为我扩展了AbstractList并且如果setand被调用,它将抛出UnsupportedOperationException If I want to get a unmodifiableList, Collections.unmodifiableList() is a good choice. 如果我想获取一个unmodifiableList, Collections.unmodifiableList()是一个不错的选择。 But remember, both of them are not deeply immutable: 但是请记住,它们都不是一成不变的:

      List<StringBuilder> list = new ArrayList<StringBuilder>();
      StringBuilder sb = new StringBuilder();
      sb.append("hello");
      list.add(sb);
      System.out.println(list);
      list = Collections.unmodifiableList(list);
      sb.append("world");
      System.out.println(list);

There is a flyweight pattern in CountingIntegerList . CountingIntegerList有一个flyweight pattern because everytime get() is called,it get caches from Integer, the source code of valueOf() : 因为每次都调用get() ,它会从Integer( valueOf()的源代码valueOf()获取缓存:

   public static Integer valueOf(int i) {
    final int offset = 128;
    if (i >= -128 && i <= 127) { // must cache 
        return IntegerCache.cache[i + offset];
    }
        return new Integer(i);
    }

Is is right? 是对的吗?

It's read-only (even immutable) because add will throw an UnsupportedOperationException as will remove . 它是只读的(甚至是不可变的),因为add会抛出UnsupportedOperationException ,而remove会抛出UnsupportedOperationException

AbstractList handles all the work of creating iterators, computing hashcodes and equality for you. AbstractList处理创建迭代器,计算哈希码和相等性的所有工作。 It's very helpful. 这非常有帮助。 It's completely unnecessary to wrap in unmodifiableList . 完全不需要包装在unmodifiableList

Later you ask whether AbstractList is used mainly to create unmodifiable lists. 稍后,您询问AbstractList是否主要用于创建不可修改的列表。 Actually it is used to create any kind of random-access list. 实际上,它用于创建任何种类的随机访问列表。 In my course in data structures, we use abstract classes such as this to save most of the work of implementing a list class. 在我的数据结构课程中,我们使用诸如此类的抽象类来节省实现列表类的大部分工作。 Even the Collection interface has 13 methods, all but two of which are implements by AbstractCollection . 甚至Collection接口也有13种方法,除了两个之外,其他所有方法都是由AbstractCollection实现的。

There is the related class AbstractSequentialList that helps create lists that are not random access (such as linked lists). 有一个相关的类AbstractSequentialList可以帮助创建不是随机访问的列表(例如链接列表)。

because set throws an UnsupportedOperationException, if not implemented. 因为set抛出UnsupportedOperationException(如果未实现)。 See Api 阿皮

您可以将您的列表包装在UnmodifiableList中

List readOnlyList = Collections.unmodifiableList(yourList)

Pass the ArrayList into Collections.unmodifiableList() 将ArrayList传递给Collections.unmodifiableList()

Returns an unmodifiable view of the specified list. 返回指定列表的不可修改视图。 This method allows modules to provide users with "read-only" access to internal lists. 此方法允许模块为用户提供对内部列表的“只读”访问权限。 Query operations on the returned list "read through" to the specified list, and attempts to modify the returned list, whether direct or via its iterator, result in an UnsupportedOperationException. 对返回列表的查询操作“读取”到指定列表,并尝试直接或通过其迭代器修改返回列表,将导致UnsupportedOperationException。 The returned list will be serializable if the specified list is serializable. 如果指定列表可序列化,则返回的列表将可序列化。 Similarly, the returned list will implement RandomAccess if the specified list does. 同样,如果指定的列表返回,则返回的列表将实现RandomAccess。

This is tricky a bit. 这有点棘手。 The list can not change and/or the elements also? 列表不能更改和/或元素也可以? ;) ;)

StringBuilder builder = new StringBuilder();
    builder.append("Hello");
    List<StringBuilder> list = new ArrayList<StringBuilder>();
    list.add(builder);

    Collection<StringBuilder> canNotChange = Collections.unmodifiableCollection(list);
    builder.append(" World");
    System.out.println(canNotChange.iterator().next());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM