【问题标题】:Need to know some basics of LinkedList class in Java需要了解Java中LinkedList类的一些基础知识
【发布时间】:2009-03-10 02:34:28
【问题描述】:
package abc;

class DependencyDataCollection
{
    private int sNo;
    private String sessionID;
    private int noOfDependency;
    private int noOfRejection;
    private int totalValue;

    /** Creates a new instance of DependencyDataCollection */
    public DependencyDataCollection(int sNo, String sessionID, int noOfDependency, int noOfRejection, int totalValue)
    {
        this.sNo = sNo;
        this.sessionID = sessionID;
        this.noOfDependency = noOfDependency;
        this.noOfRejection = noOfRejection;
        this.totalValue = totalValue;
    }

    public int getSNo()
    {
        return sNo;
    }

    public String getSessionID()
    {
        return sessionID;
    }

    public int getNoOfDependency()
    {
        return noOfDependency;
    }

    public int getNoOfRejection()
    {
        return noOfRejection;
    }

    public int getTotalValue()
    {
        return totalValue;
    }
}

public class DependencyStack {

    LinkedList lList;

    /** Creates a new instance of DependencyStack */
    public DependencyStack()
    {
        lList = new LinkedList();
    }

    public void add(int sNo, String sessionID, int noOfDependency, int noOfRejection, int totalValue)
    {
        lList.add(new DependencyDataCollection(sNo,sessionID,noOfDependency,noOfRejection,totalValue));
    }

    public int size()
    {
        return lList.size();
    }

    public void show()
    {
        for(int i=0;i<lList.size();i++)
        {
            DependencyDataCollection ddc = (DependencyDataCollection)lList.get(i);
            System.out.println(ddc.getSNo()+"   "+ddc.getSessionID()+"   "+ddc.getNoOfDependency()+"     "+ddc.getNoOfRejection()+"      "+ddc.getTotalValue());
        }
    }

    public int returnIndexOfSession(String sessionID)
    {
        DependencyDataCollection ddc = null;
        for(int i=0;i<lList.size();i++)
        {
            ddc = (DependencyDataCollection)lList.get(i);
            if(ddc.getSessionID().equals(sessionID))
                break;
        }
        return ddc.getSNo();
    }

    public static void main(String args[])
    {
        DependencyStack ds = new DependencyStack();
        ds.add(1,"a",0,0,0);
        ds.add(2,"b",0,0,0);
        ds.show();

        //System.out.println(ds.returnIndexOfSession("a"));

//        DependencyDataCollection ddc = new DependencyDataCollection(1,"a",0,0,0);
//        System.out.println(ds.indexOf(ddc));
    }
}

这是一个简单的 java 链表程序,它使用 java.util 包中的内置链表类。链表用于存储不同数量的数据,使用 DependencyDataCollection 类..

现在我的问题是

1) 请评估这个程序, 我尊重所有的 java 私人成员等概念 访问,我已经完成了,等等。

2) 我在寻找 特定会话的索引。

例如节点 1 包含 1,"a",0,0,0......节点 2 包含 2,"b",0,0,0

现在我想找到 indexOf 包含其中之一的节点 数据为“b”或“a”。什么可能是最短的内置方法可以做到这一点,因为我制作了一个名为“public int returnIndexOfSession(String sessionID)”的函数,它使用了for循环,我发现这非常耗时..还有其他出路吗? .

由于我是java新手,请评估和指导。

【问题讨论】:

    标签: java


    【解决方案1】:

    这是我要做的改变,理由在 cmets。

    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.io.Writer;
    import java.util.ArrayList;
    import java.util.List;
    
    
    class DependencyDataCollection
    {
        // makte them fnal, then you hava an immutible object and your code is much safer.
        // in your case you had noset methods so it was safe, but always try to make things final.
        private final int sNo;
        private final String sessionID;
        private final int noOfDependency;
        private final int noOfRejection;
        private final int totalValue;
    
        public DependencyDataCollection(final int    sNo, 
                                        final String sessionID, 
                                        final int    noOfDependency, 
                                        final int    noOfRejection, 
                                        final int    totalValue)
        {
            this.sNo            = sNo;
            this.sessionID      = sessionID;
            this.noOfDependency = noOfDependency;
            this.noOfRejection  = noOfRejection;
            this.totalValue     = totalValue;
        }
    
        public int getSNo()
        {
            return sNo;
        }
    
        public String getSessionID()
        {
            return sessionID;
        }
    
        public int getNoOfDependency()
        {
            return noOfDependency;
        }
    
        public int getNoOfRejection()
        {
            return noOfRejection;
        }
    
        public int getTotalValue()
        {
            return totalValue;
        }
    }
    
    class DependencyStack
    {
        // change the type to be as generic as poosible - List interface
        // added generics so you get compile time safety and don't use casts later on
        // renamed it to something meaningful
        private final List<DependencyDataCollection> dependencies;
    
        // use an ArrayList instead of a LinkedList, it'll be faster since you are not inserting/deleting
        // into the middle of the list
        {
            dependencies = new ArrayList<DependencyDataCollection>();
        }
    
        // your Stack shouldn't know how to make the collections... (in my opinion)
        public void add(final DependencyDataCollection ddc)
        {
            dependencies.add(ddc);
        }
    
        public int size()
        {
            return dependencies.size();
        }
    
        // the next 3 methods are just convenience since you don't know if someione
        // will want to write to a file or a writer instead of a stream
        public void show()
        {
            show(System.out);
        }
    
        public void show(final OutputStream out)
        {
            show(new OutputStreamWriter(out));
        }
    
        public void show(final Writer writer)
        {
            show(new PrintWriter(writer));
        }
    
        public void show(final PrintWriter writer)
        {
            // use the new for-each instead of the old style for loop
            // this also uses an iterator which is faster than calling get
            // (well on an ArrayList it probably is about the same, but a LinkedList it'll be faster)
            for(final DependencyDataCollection ddc : dependencies)
            {
                writer.println(ddc.getSNo()            + "   " +
                               ddc.getSessionID()      + "   " +
                               ddc.getNoOfDependency() + "   " +
                               ddc.getNoOfRejection()  + "   " +
                               ddc.getTotalValue());
            }
        }
    
        public int returnIndexOfSession(final String sessionID)
        {
            DependencyDataCollection foundDDC;
            final int                retVal;
    
            foundDDC = null;
    
            for(final DependencyDataCollection ddc : dependencies)
            {
                if(ddc.getSessionID().equals(sessionID))
                {
                    foundDDC = ddc;
                    break;
                }
            }
    
            // deal with the fact that you might have not found the item and it would be null.
            // this assumes -1 is an invalid session id
            if(foundDDC == null)
            {
                retVal = -1;
            }
            else
            {
                retVal = foundDDC.getSNo();
            }
    
            return (retVal);
        }
    
        public static void main(final String[] args)
        {
            DependencyStack ds = new DependencyStack();
            ds.add(new DependencyDataCollection(1,"a",0,0,0));
            ds.add(new DependencyDataCollection(1,"a",0,0,0));
            ds.show();
    
            //System.out.println(ds.returnIndexOfSession("a"));
    
    //        DependencyDataCollection ddc = new DependencyDataCollection(1,"a",0,0,0);
    //        System.out.println(ds.indexOf(ddc));
        }
    }
    

    编辑:

    这将加快查找(和删除)的速度。

    class DependencyStack
    {
        // A Map provides quick lookup
        private final Map<String, DependencyDataCollection> dependencies;
    
        // a LinkedHashMap allows for quick lookup, but iterates in the order they were added... if that matters for show.
        {
            dependencies = new LinkedHashMap<String, DependencyDataCollection>();
        }
    
        // your Stack shouldn't know how to make the collections... (in my opinion)
        public void add(final DependencyDataCollection ddc)
        {
            if(ddc == null)
            {
                throw new IllegalArgumentException("ddc cannot be null");
            }
    
            dependencies.put(ddc.getSessionID(), ddc);
        }
    
        public int size()
        {
            return dependencies.size();
        }
    
        // the next 3 methods are just convenience since you don't know if someione
        // will want to write to a file or a writer instead of a stream
        public void show()
        {
            show(System.out);
        }
    
        public void show(final OutputStream out)
        {
            show(new OutputStreamWriter(out));
        }
    
        public void show(final Writer writer)
        {
            show(new PrintWriter(writer));
        }
    
        public void show(final PrintWriter writer)
        {
            // use the new for-each instead of the old style for loop
            // this also uses an iterator which is faster than calling get
            // (well on an ArrayList it probably is about the same, but a LinkedList it'll be faster)
            for(final DependencyDataCollection ddc : dependencies.values())
            {
                writer.println(ddc.getSNo()            + "   " +
                               ddc.getSessionID()      + "   " +
                               ddc.getNoOfDependency() + "   " +
                               ddc.getNoOfRejection()  + "   " +
                               ddc.getTotalValue());
            }
        }
    
        public int returnIndexOfSession(final String sessionID)
        {
            final DependencyDataCollection ddc;
            final int                      retVal;
    
            if(sessionID == null)
            {
                throw new IllegalArgumentException("sessionID cannot be null");
            }
    
            // get it if it exists, this is much faster then looping through a list
            ddc = dependencies.get(sessionID);
    
            // deal with the fact that you might have not found the item and it would be null.
            // this assumes -1 is an invalid session id
            if(ddc == null)
            {
                retVal = -1;
            }
            else
            {
                retVal = ddc.getSNo();
            }
    
            return (retVal);
        }
    
        public static void main(final String[] args)
        {
            DependencyStack ds = new DependencyStack();
            ds.add(new DependencyDataCollection(1,"a",0,0,0));
            ds.add(new DependencyDataCollection(1,"a",0,0,0));
            ds.show();
    
            //System.out.println(ds.returnIndexOfSession("a"));
    
    //        DependencyDataCollection ddc = new DependencyDataCollection(1,"a",0,0,0);
    //        System.out.println(ds.indexOf(ddc));
        }
    }
    

    【讨论】:

    • 我以后必须删除一个节点,这就是我使用链表的原因...评论..
    • 随着程序的进行,我必须更改 sno、sessionID 等的值。所以我认为我不能使用 final .. 请对此发表评论..
    • 不过,非常感谢先生,您的可编辑程序,教会了我很多新东西......非常感谢......
    • 如果您必须更改它们,那么是的,它们不能是最终的。如果 sessionID 发生更改,您将无法使用 Map 版本。此外,Map 还假设 DependencyDataCollection 的 equals 和 hashCode 方法被覆盖
    • 地图工作得很好......手......我们也可以从这个地图类型声明中删除一个节点??你也可以给我提供我们可以获得JavaDocs的指南吗?
    【解决方案2】:

    突出的一点是缺少 javadoc 样式的 cmets (来自http://en.wikipedia.org/wiki/Javadoc

    /** *验证国际象棋移动。使用 {@link #doMove(int, int, int, int)} 移动一块。 * * @param theFromFile 文件从中移动一块 * @param theFromRank 排名从哪个棋子被移动 * @param theToFile 一块被移动到的文件 * @param theToRank 一块被移动到的排名 * @return 如果棋步有效,则返回 true,否则返回 false */

    【讨论】:

    • 感谢您的回答,真的很感激......现在会注意到这一点......
    【解决方案3】:

    你有一个好的开始。您可以进行的改进:

    • 泛型。您的链接列表可能是

      LinkedList lList; 这使您可以进行类型检查。

    • 您已经看到,您的链表不便于搜索 - 您必须检查每个值,这既慢又笨重。这就是人们使用哈希图的原因。

    • 查找构建器模式以找到绕过长长的构造器参数列表的方法。

    【讨论】:

    • 你能给我一些使用Hashmaps的例子吗..一些参考资料或网站...
    【解决方案4】:

    1) 为什么不使用泛型:

    LinkedList<DependencyDataCollection> lList;
    

    2)这就是LinkedList的缺点,你还不如使用HashMap或者其他数据结构

    【讨论】:

    • 你能给我一些参考网站或数据结构的名称,可以忽略链表的这个缺点..
    • @Kool Techie:HashMap 基本上是一个键值对的数据结构。你可以用一个值映射一个键,你可以用这个键取回值。我建议使用 HashMap,因为您似乎需要使用另一个值来获取一个值。更多关于 HashMap:lmgtfy.com/?q=how+to+use+hashmap
    【解决方案5】:

    你想使用泛型:

    List<DependencyDataCollection> lList;
    

    此外,在您的变量定义中,您应该使用接口 List 而不是具体类型 (LinkedList)。

    要使 indexOf 工作,您的元素类型 (DependencyDataCollection) 需要实现比较器以实现相等性:

    class DependencyDataCollection{
    
      @Override
      public boolean equals(Object o){
        ...
      }
    }
    

    然后您可以使用 List 接口提供的内置 indexOf()。然而,它将执行与您现在执行的相同类型的循环。如果这太耗时(真的吗?),那么您需要一个哈希支持列表或其他东西(在这种情况下,您还需要实现 hashCode())。

    更新:它将执行相同类型的循环,但比您现在更有效。不要通过索引访问链表,它不是为此构建的,使用 foreach 循环或迭代器(或 ArrayList):

        for(DependencyDataCollection d: iList){
        ... }
    

    【讨论】:

      【解决方案6】:

      在最近的 Java 版本中,您可以使用 generics,这样您就不必强制转换调用 lList.get(i) 时生成的对象。例如:

      LinkedList<DependencyDataCollection> lList = new LinkedList<DependencyDataCollection>();
      
      ...
      
      DependencyDataCollection ddc = lList.get(0);
      

      要获取特定元素的索引,请手动遍历列表。对于列表范围内的每个索引 i,在此处获取 DependencyDataCollection 并查看它是否具有您想要的属性。如果是,请保存索引。

      【讨论】:

        【解决方案7】:

        LinkedList 在 java.util 中,可以包含任何类型的类。例如,我使用一个名为 Application 的类。所以在下面的代码中,我只有一个应用程序列表。然后我把一个应用程序放在列表中。我还可以遍历我的应用程序以对我的对象做任何我想做的事情。

                LinkedList<Application> app = new LinkedList<Application>();
        
                    app.add(new Application("firefox"));
        
            Iterator<Application> iterable = app.iterator();
            while(iterable.hasNext()){
                Application eachapp = iterable.next();
            }
        

        如果你需要找到一个带有 indexOf 的对象,你可以在我的情况下为你的对象覆盖 equal 方法“应用程序”,所以如果在 equal 我声明它并且应用程序等于和其他应用程序,如果字段名称相同,那么

        app.indexOf(new Application("firefox")) 将返回我刚刚插入的应用程序的索引。

        【讨论】:

        • 谢谢先生,回答..我用过LinkedHashMap类,看起来很满意..如果它比LinkedList有任何缺点,请评论..
        • 不,不同的 java 对象,映射是一组包含键和值的条目。 LinkedList 它只是一个对象列表。使用linkedlist,您可以对类似的东西进行FIFO LIFO 排队。使用映射,它更像是一组键,因此您可以找到一个值。
        猜你喜欢
        • 1970-01-01
        • 2011-06-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-27
        • 2011-08-11
        • 2021-04-07
        • 2011-06-14
        相关资源
        最近更新 更多