0

我写了一个要存储在链表中的类,该类中有 3 个字段。其中一个字段是一个字符串,我想在链接列表中搜索它。

例子

LinkedList
      Obj1
          String name = "first";
          int age = 2;
          int size = 4;
      Obj2
          String name = "second";
          int age = 3;
          int size = 6;
      Obj3
          String name = "third";
          int age = 5;
          int size = 8;

如果这是使用给定字段存储这三个对象的链表,有没有办法在链表中搜索名称为“second”的对象?

4

5 回答 5

2

您可以通过迭代搜索列表中的项目

// Iterate over each object within the list
for(YourClass obj : yourLinkedList) {

    // Check if the object's name matches the criteria, in this case, the name
    // of the object has to match "second"
    if (obj.name.equals("second")) {

        // If we are within this block, it means that we found the object that has
        // its name set as "second".
        return obj;
    }
}

您还可以制作一种使事情更优雅的方法

public YourClass findByName(String name) {
    for(YourClass obj : yourLinkedList) {
        if (obj.name.equals(name)) {
            return obj;
        }
    }
    return null;
}

并通过以下方式使用它

YourClass object = findByName("second");
于 2013-04-04T04:55:02.543 回答
1

这是实现比较器的另一种方法(以防万一)。

我发现如果你明确地实现 Comparator 会更容易理解:

class PersonAgeComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person person2) {
        return p1.getAge().compareTo(p2.getAge());
    }
}

您可以像这样使用上面的内容:

Comparator ageComparator = new PersonAgeComparator();
List<Person> personList = // populate list somehow
Person fourYearOld = new Person();
fourYearOld.setAge(4);
for (Person p : personList) {
    if (ageComparator.compare(fourYearOld, p) == 0) {
        System.out.println(p.getName() + " is 4 years old");
    }
}

对于这个简单的示例,这没有多大意义。

如果您有几种复杂的方法来比较人们(按身高、按调整后的收入、按他们住过多少个州等),那将是理想的选择。

于 2013-04-04T05:27:49.703 回答
1

最简单的方法当然是遍历集合中的每个元素,检查它是否匹配您的过滤条件,然后选择找到的匹配项。但是,您需要执行的次数越多,过滤条件就越复杂,这会变得乏味。我建议使用预先存在的库来有效地完成任务。这是使用Google-Collections的示例:

final List<SomeObj> listObjs = Arrays.asList(
        new SomeObj("first", 2, 4), new SomeObj("second", 3, 6),
        new SomeObj("third", 5, 8));

final Iterable<SomeObj> filtered = Iterables.filter(listObjs,
        new Predicate<SomeObj>() {

            @Override
            public boolean apply(final SomeObj obj) {
                return "second".equals(obj.getName());
            }
        });

for (final SomeObj obj : filtered) {
    System.out.println(obj);
}

显示的代码将选择列表中名称属性为“second”的所有对象。显然,谓词不必是匿名内部类 - 如果您需要重用它,您只需将其分解为独立类。

于 2013-04-04T05:28:25.263 回答
1

看一下java.util.Comprator接口。您可以编写一种方法来遍历 List 并使用比较器来查找您所追求的。

类似的东西(未编译):

for(final T value : list)
{
    if(comparator.compare(value, desired) == 0)
    {
        // match
    }
}

在您的比较器中,您可以让它执行您想要的任何比较。

这是一个工作示例:

public class JavaApplication4 
{
    public static void main(String[] args) 
    {
        final List<Data> list;
        final List<Data> a;
        final List<Data> b;

        list = new ArrayList<Data>();
        list.add(new Data("Foo", 1));
        list.add(new Data("Bar", 10));
        list.add(new Data("Car", 10));

        a = find(list, 
                 new Data("Bar", 0),
                 new Comparator<Data>()
                 {
                    @Override
                    public int compare(final Data o1, 
                                       final Data o2) 
                    { 
                        return (o1.name.compareTo(o2.name));
                    }                  
                 });

        b = find(list, 
                 new Data(null, 10),
                 new Comparator<Data>()
                 {
                    @Override
                    public int compare(final Data o1, 
                                       final Data o2) 
                    { 
                        return (o1.count - o2.count);
                    }                  
                 });

        System.out.println(a.size());
        System.out.println(b.size());
    }

    private static List<Data> find(final List<Data>       list,
                                   final Data             desired,
                                   final Comparator<Data> comprator)
    {
        final List<Data> results;

        results = new ArrayList(list.size());

        for(final Data data : list)
        {
            if(comprator.compare(desired, data) == 0)
            {
                results.add(data);
            }
        }

        return (results);
    }

    private static class Data
    {
        private final String name;
        private final int count;

        Data(final String nm,
             final int    c)
        {
            name  = nm;
            count = c;
        }
    }
}

这是该find方法的通用版本。使用这种方法,您永远不必再次编写 find 方法,使用在迭代代码中嵌入匹配逻辑的方法意味着您必须为每组新的匹配逻辑重新编写迭代逻辑。

private static <T> List<T> find(final List<T>       list,
                                final T             desired,
                                final Comparator<T> comprator)
{
    final List<T> results;

    results = new ArrayList(list.size());

    for(final T value : list)
    {
        if(comprator.compare(desired, value) == 0)
        {
            results.add(value);
        }
    }

    return (results);
}
于 2013-04-04T04:56:31.853 回答
0

您可以通过它并完成它,或者还有其他方法。

您需要覆盖类中的 equals 方法(以及 hashcode 方法)。

在您根据需要覆盖等于之后,在这种情况下比较名称,创建一个具有相同名称的新对象并调用 LinkedList 的 remove(Object o) 方法并获取该对象。

您应该注意,使用这种方法,您的对象相等性将由名称定义,并且该条目将从 LinkedList 中删除

于 2013-04-04T04:59:13.283 回答