Java 筛选链接列表的首选方法

Java 筛选链接列表的首选方法,java,Java,TestListRemoveFunctional和TestListRemoveUpdateEstate类在LinkedList的运行时执行筛选 我认为TestListRemoveFunctional实现更干净,因为它不更新状态,但效率较低,因为它在每个过滤步骤创建一个新列表 虽然TestListRemoveFunctional和TestListRemoveUpdateEstate本质上执行相同的作业,但TestListRemoveFunctional更可取,因为它不更新状态,这与TestList

TestListRemoveFunctional和TestListRemoveUpdateEstate类在LinkedList的运行时执行筛选

我认为TestListRemoveFunctional实现更干净,因为它不更新状态,但效率较低,因为它在每个过滤步骤创建一个新列表

虽然TestListRemoveFunctional和TestListRemoveUpdateEstate本质上执行相同的作业,但TestListRemoveFunctional更可取,因为它不更新状态,这与TestListRemoveUpdateEstate中的过滤实现不同

请注意,我仅限于不使用java8 lambdas或project Guava lambdas

可以确认我的断言TestListRemoveFunctional更可取吗

import java.util.LinkedList;

public class TestListRemoveFunctional {

    public static void main(String args[]) {

        TestListRemoveFunctional t = new TestListRemoveFunctional();
        LinkedList<MyObj> l = new LinkedList<MyObj>();
        l.add(new MyObj("1"));
        l.add(new MyObj("2"));

        System.out.println("size : "+l.size());

        LinkedList<MyObj> f1 = t.filterItem1(l);
        System.out.println("size : "+f1.size());

        LinkedList<MyObj> f2 = t.filterItem2(f1);
        System.out.println("size : "+f2.size());
    }

    private LinkedList<MyObj> filterItem1(LinkedList<MyObj> l) {

        LinkedList<MyObj> toReturn = new LinkedList<MyObj>();
        for (MyObj myObj : l) {

            if (!myObj.param.equalsIgnoreCase("1")) {
                toReturn.add(myObj);
            }
        }
        return toReturn;
    }

    private LinkedList<MyObj> filterItem2(LinkedList<MyObj> l) {

        LinkedList<MyObj> toReturn = new LinkedList<MyObj>();
        for (MyObj myObj : l) {

            if (!myObj.param.equalsIgnoreCase("2")) {
                System.out.println(myObj.param);
                toReturn.add(myObj);
            }
        }
        return toReturn;
    }



    private static class MyObj {

        public String param;

        public MyObj(String param) {
            this.param = param;
        }
    }

}

********************************************************************************************


import java.util.Iterator;
import java.util.LinkedList;

public class TestListRemoveUpdateState {

    public static void main(String args[]) {

        TestListRemoveUpdateState t = new TestListRemoveUpdateState();
        LinkedList<MyObj> l = new LinkedList<MyObj>();
        l.add(new MyObj("1"));
        l.add(new MyObj("2"));

        System.out.println("size is : " + l.size());

        t.filterItem1(l);       
        System.out.println("size is : " + l.size());

        t.filterItem2(l);   
        System.out.println("size is : " + l.size());
    }

    private void filterItem1(LinkedList<MyObj> l) {

        Iterator<MyObj> iter = l.iterator();
        while (iter.hasNext()) {
            MyObj myObj = iter.next();

            if (myObj.param.equalsIgnoreCase("1")) {
                iter.remove();
            }
        }
    }

    private void filterItem2(LinkedList<MyObj> l) {

        Iterator<MyObj> iter = l.iterator();
        while (iter.hasNext()) {
            MyObj myObj = iter.next();

            if (myObj.param.equalsIgnoreCase("2")) {
                iter.remove();
            }
        }
    }

    private static class MyObj {

        public String param;

        public MyObj(String param) {
            this.param = param;
        }
    }

}
import java.util.LinkedList;
公共类TestListRemoveFunctional{
公共静态void main(字符串参数[]){
TestListRemoveFunctional t=新的TestListRemoveFunctional();
LinkedList l=新建LinkedList();
l、 增加(新的MyObj(“1”));
l、 增加(新的MyObj(“2”));
System.out.println(“大小:+l.size());
LinkedList f1=t.filterItem1(l);
System.out.println(“大小:+f1.size());
LinkedList f2=t.filterItem2(f1);
System.out.println(“大小:+f2.size());
}
专用LinkedList筛选器项1(LinkedList l){
LinkedList toReturn=新建LinkedList();
对于(MyObj MyObj:l){
如果(!myObj.param.equalsIgnoreCase(“1”)){
toReturn.add(myObj);
}
}
回归回归;
}
专用LinkedList筛选器项2(LinkedList l){
LinkedList toReturn=新建LinkedList();
对于(MyObj MyObj:l){
如果(!myObj.param.equalsIgnoreCase(“2”)){
System.out.println(myObj.param);
toReturn.add(myObj);
}
}
回归回归;
}
私有静态类MyObj{
公共字符串参数;
公共MyObj(字符串参数){
this.param=param;
}
}
}
********************************************************************************************
导入java.util.Iterator;
导入java.util.LinkedList;
公共类TestListRemoveUpdateEstate{
公共静态void main(字符串参数[]){
TestListRemoveUpdateEstate t=新的TestListRemoveUpdateEstate();
LinkedList l=新建LinkedList();
l、 增加(新的MyObj(“1”));
l、 增加(新的MyObj(“2”));
System.out.println(“大小为:+l.size());
t、 过滤器项目1(l);
System.out.println(“大小为:+l.size());
t、 过滤器EM2(l);
System.out.println(“大小为:+l.size());
}
私有无效筛选器项1(链接列表l){
迭代器iter=l.Iterator();
while(iter.hasNext()){
MyObj MyObj=iter.next();
if(myObj.param.equalsIgnoreCase(“1”)){
iter.remove();
}
}
}
私有无效筛选器EM2(链接列表l){
迭代器iter=l.Iterator();
while(iter.hasNext()){
MyObj MyObj=iter.next();
if(myObj.param.equalsIgnoreCase(“2”)){
iter.remove();
}
}
}
私有静态类MyObj{
公共字符串参数;
公共MyObj(字符串参数){
this.param=param;
}
}
}

什么更好?保持原始项目或效率的状态?为了证明在这些类别中的任何选择是正确的,你必须陈述你认为最重要的特质,因为你没有一个没有另一个。 顺便说一句,两者在效率和可读性方面都有一些缺陷

更新

(可读性)不需要两种过滤方法(一种用于项目1,一种用于项目2),只需要一种方法:List filterItem(List l,T item)

(可重用性)使用泛型而不是特定类型。而不是将它们声明为。通过这种方式,您可以将这些类和方法用于任何组件的列表

如果将参数声明为List而不是LinkedList,则可以提高这些方法的可用性

(灵活性)如果将返回类型声明为List,则可以更改要使用的List的特定实现,同时避免类的用户必须重新编写代码

最好使用commons collections之类的“过滤器”类

(效率)在使用equalsIgnoreCase和不区分大小写的字符串的筛选器方法的特定实现中,在这种情况下可以使用equals


(安全)列表可以包含空值,具体取决于实现。特别是,LinkedList可以,因此在访问列表元素和访问MyObj.param的值时,这些筛选器中存在NullPointerException的风险。

这取决于您所说的“首选”是什么意思。当您在列表中进行迭代时,可以使用迭代器安全地从列表中删除元素(正如您所做的那样)

如果您查看其他方法,那么是的,您正在创建一个新的链表。在最坏的情况下,如果不过滤任何内容,则使用
O(2*n)
空格。所以这取决于你是否愿意使用更多的内存


我认为第一种方法很好,因为根据文档,使用
iterator.remove()
是完全安全的。只有当您不能保证集合将被其他人同时修改(即并发访问)时,才是不安全的。

链表的优点之一是具有非常高效的
删除操作

让我们考虑下面的链表(在java中,链表实际上是双链表):

这正是iterator.remove()所做的

因此,
TestListRemoveUpdateState
更有效,因为您正在处理
LinkedList


作为旁注,
ArrayList
上的首选方法是
TestL
e1 <-> e2 <-> e3 <-> e4 <-> e5
e3.previous.next = e3.next;
e3.next.previous = e3.previous;
e3.next = null;
e3.previous = null;
e3.element = null;