【问题标题】:How to implement a fixed size "list" in Java?如何在 Java 中实现固定大小的“列表”?
【发布时间】:2012-02-17 00:53:54
【问题描述】:

既然 Java 核心库没有这样的集合,那么数组是不是最好的选择,尤其是在不想依赖第三方库的情况下?

【问题讨论】:

  • 当您尝试将项目添加到完整列表时,您想要什么行为?您可能还应该有一个方法来检查是否有一些空间。
  • Arrays.asList 正是这样做的。
  • 问题是模棱两可的:列表是固定的?还是它的大小是固定的?

标签: java arrays list fixed


【解决方案1】:
 public class libsystem extends javax.swing.JFrame {

   //public static ArrayList<books> al = new ArrayList<books>();
   public static List<books> al = Arrays.asList(new books[100]);
   public libsystem() {
    initComponents();
  }
   String msg =jTextArea1.getText();

    try {
        FileWriter fs=new FileWriter("library.txt");
        try(
            BufferedWriter out= new BufferedWriter(fs)){;
            out.write(msg);
        }
       } catch (Exception e){
        System.err.println("wrong" + e.getMessage());                                
  }
    String line;
    String id,name,type;
    try{
        FileReader in=new FileReader("library.txt");
        try (BufferedReader br = new BufferedReader(in)) {      

            while((line=br.readLine())!=null){      
                StringTokenizer st1 = new StringTokenizer(line,",");    
                while(st1.hasMoreTokens()){     
                    id=st1.nextToken();     
                    name=st1.nextToken();    
                    type=st1.nextToken();   
      books book=new books(id,name,type);    
                al.add(book);     
              }     
                br.close();    
        for(int i=0;i<al.size();i++){    
      books obj = al.get(i);    

        System.out.println("Book NAme :"+obj.getName()+ "\n" +"                                       Name:"+obj.getAuthor()+ "\n"+"Type :"+obj.getSubject()+"\n");                 

        }         

【讨论】:

    【解决方案2】:

    我可能会被烧死,但您也可以为此使用ArrayBlockingQueue。这提供了能够使用常规 Collection 方法的好处。

    【讨论】:

    • 它不提供对 all 列表方法的访问(即它不实现任何类型的列表)——尤其是基于索引的访问方法,它(对于无论如何我)将是首先使用列表的主要原因。
    • 没错,我更新了我的答案以反映它确实实现了 Collection 操作,而不是 List。
    【解决方案3】:

    我会围绕ArrayList 编写一个包装类,在addaddAll 方法中,我会在添加新元素之前检查列表的大小。如果您已达到最大大小,则可以抛出异常(或不执行任何操作,具体取决于您在代码中真正想要执行的操作)。

    这是一个简短的例子:

    public class SizeLimitedArray<E> implements java.util.List<E>
        {
        private static final int DEFAULT_SIZE_LIMIT = 10;
        private ArrayList<E> myList;
        private int maxSize;
    
        public SizeLimitedArray ()
            {
            this (DEFAULT_SIZE_LIMIT);
            }
    
        public SizeLimitedArray (int size)
            {
            myList = new ArrayList<E> (size);
            maxSize = size;
            }
    
        @Override
        public boolean add (E objectToAdd)
            {
            if (myList.size () > maxSize)
                {
                throw new IllegalStateException ("The array is full");
                }
    
            return myList.add (objectToAdd);
            }
    
        @Override
        public boolean addAll (Collection collectionToAdd)
            {
            if (myList.size () + collectionToAdd.size () > maxSize)
                {
                throw new IllegalStateException ("The array is full");
                }
    
            return myList.addAll (collectionToAdd);
            }
    
        // Rest of class omitted for brevity
        }
    

    【讨论】:

      【解决方案4】:

      您可以使用数组,或使用所需大小预初始化的ArrayList&lt;E&gt;

      如果你想主动防止列表的扩展,那么使用数组可能是最简单的。

      【讨论】:

      • 但是如果我在ArrayList 实例中添加一个对象会导致它超出它的大小,它不会自动扩展吗?
      • @mre:如果你这样做,它会的。你是说你想积极阻止自己这样做吗?
      • @aix,是的,我想积极阻止自己这样做。
      • @mre:很公平。在这种情况下,我个人会坚持使用数组。
      • 矫枉过正,这几乎就是 Arrays.asList 自己实现的
      【解决方案5】:

      使用Collections.unmodifiableList(List&lt;T&gt; list)。这将返回一个通用的 List&lt;T&gt; 对象,如果您尝试添加(或删除)元素,该对象将抛出 UnsupportedOperationException

      【讨论】:

        【解决方案6】:

        只需实现您自己的。您可以使用基于代理的方法。定义由ArrayList 支持的您自己的列表。将内部列表设为私有。还实现一个简单的limit 字段,该字段具有默认值,也可以通过构造函数进行设置。

        您的列表将实现List,并且对于修改内部列表的每个方法,相应地递增和递减计数。如果大小超过限制,则抛出某种异常。类似的东西

        public class FixedList implements List {
            private ArrayList<E> list = new ArrayList<E>();
            private int limit = 10; // default
        
            FixedList(){} // default constructor
        
            FixedList(int limit) {
                this.limit = limit;
            }
        
            public boolean add(E object) {
               if (this.list.size() == limit - 1) {
                   // throw some sort of LimitExceeded Runtime Exception
               }
        
               this.list.add(object);
            }
            ...
        }
        

        您将不得不处理泛型,并记住支持一次添加多个东西的情况addAll

        【讨论】:

        • 所以我们采用了一个ArrayList,它允许我们动态扩展数组的大小,然后改变它的行为,这样我们就不能再这样做了?是的,not not xx 相同,但这毫无意义不是吗?
        • 我不确定你的意思是什么。你是说他的自定义列表应该由数组支持吗?
        • 好吧,您删除了 ArrayList 在一个简单数组上添加的所有附加功能,因此我们可以只使用数组本身 - 或者如果我们需要 add 和 co 函数,只需通过一个数组也会更简单。
        • 是的,这是一种有效的方法,尽管我不同意我“删除了所有附加功能......”。我个人会在数组上使用 List ,因为我不想维护指向当前索引的指针以及所有这些,以及泛型,但如果适合他的目的,OP 可以使用数组。
        【解决方案7】:

        例如,您可以从类ArrayList 继承并重新实现add 方法,使其无法添加超过给定数量的元素。或者,更好地作为 Laf 的指针,使用组合:

        public class MyArrayList<T> {
             private ArrayList<T> innerList;
             private int maxSize;
        
             public boolean add(T item) {
                 if(innerList.size() < maxSize) {
                     return innerList.add(item);
                 } else {
                     return false;
                 }
             }
        }
        

        【讨论】:

        • 这就是我想如果我不想使用数组就必须去的地方。
        • 在这种情况下我不推荐继承,而是一个包装类。覆盖add 方法可能会产生更多问题,因为您变得依赖于ArrayList 实现。这是 Josh Bloch 在他的Effective Java一书中提到的。
        • @mre:我已经发布了一个示例。
        【解决方案8】:

        Arrays.asList(T ...)Returns a fixed-size list backed by the specified array

        Object[] array = new Object[10];
        List<Object> fixedList = Arrays.asList(array);
        

        【讨论】:

        • 那么,如果我尝试向已包含 10 个对象的 fixedList 添加另一个对象,它会抛出异常还是静默失败?
        • add 会给你 UnsupportedOperationException,你只能使用 set 和 get,基本上表现得像一个数组。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-09
        • 1970-01-01
        • 2011-08-16
        • 2012-05-23
        • 1970-01-01
        • 2019-01-04
        • 1970-01-01
        相关资源
        最近更新 更多