我需要从给定的超级列表中获取子列表,如下所述。
假设我有一个“人物”对象的超级列表,如下所示:
List<Person> personsList = new ArrayList<>();
personsList.add(new Person("John", 28));
personsList.add(new Person("Paul", 29));
personsList.add(new Person("Adam", 30));
personsList.add(new Person("Peter", 31));
personsList.add(new Person("Pat", 32));
让Person类定义如下:
class Person {
public String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return name + ": " + age;
}
}
给出这样的子列表:
String [] names = {"John", "Paul", "Adam"};
List<String> namesList = Arrays.asList(names);
我想获取姓名为John
,Paul
和Adam
的人物对象。
我是Java流的新手,这是我到目前为止所做的尝试,以满足我的要求。
List<Person> finalList = personsList.stream().filter(p -> namesList.contains(p.name))
.collect(Collectors.toCollection(() -> new ArrayList<Person>()));
我得到了理想的结果,但我想知道是否还有其他有效的方法来实现这一点(我主要看一下namesList.contains(p.name)的效率有点低。)
如果有更好的方法,请告诉我。
答案 0 :(得分:4)
假设在数组中有重复的名称是没有意义的,最好的方法是在Set<T>
名称中找到名称。这很容易实现。将数组转换为List,并在接受任何集合后立即将其包含在HashSet<T>
的构造函数中。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" class="js-add-category">Add Category</button><br><br>
<div class="main-content" data-count="1">
<div class="typical serv-content">
<div class="serv-content">
<div class="title-content">
<input type="text" id="name-title-#cat#" class="name-title" value="name-#cat#">
</div>
<div class="action-btn">
<button type="button" class="js-add-section">Add Section</button>
<button type="button" class="js-save-section">Save</button>
</div>
</div>
</div>
<div class="typical cars-item">
<div class="cars-item js-cars-item" data-count="1">
<ul>
<li>
<input type="checkbox" id="car-#cat#-#sec#-1">
<label for="car-#cat#-#sec#-1"><i class="icon-tick"></i></label>
</li>
<li>
<input type="checkbox" id="car-#cat#-#sec#-2">
<label for="car-#cat#-#sec#-2"><i class="icon-tick"></i></label>
</li>
<li>
<input type="checkbox" id="car-#cat#-#sec#-3">
<label for="car-#cat#-#sec#-3"><i class="icon-tick"></i></label>
</li>
</ul>
<div class="footer">
<span class="num"> Section #sec# </span>
</div>
</div>
</div>
</div>
现在使用Stream-API与您尝试的相同。仅使用静态方法Collectors.toList()
。
String [] names = {"John", "Paul", "Adam"};
Set<String> set = new HashSet<>(Arrays.asList(names));
结果将仅包含List<Person> list= personsList.stream()
.filter(i -> set.contains(i.getName()))
.collect(Collectors.toList());
,John
和Paul
个人&#39;对象。
答案 1 :(得分:2)
将nameList
定义为Set会更有效,但如果列表中只包含3个名称,则差异不会明显。
这样的事情:
Set<String> namesList = new HashSet<> (Arrays.asList("John", "Paul", "Adam"));
List<Person> finalList = personsList.stream()
.filter(p -> namesList.contains(p.name))
.collect(Collectors.toList());
注意:我还将收藏家更改为toList
,因为这是您显然需要的。