我是Java 8 Stream API的新手。我有以下要求我的订购规则是:“A”,“C”,“D”,“B”
我的结果是包含8-9个元素和重复元素的对象。
以下是我的代码:
public class A
{
private String name;
public A()
{
}
public A(String name )
{
this.name=name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "A [name=" + name + "]";
}
我有另一个班级:
public class B
{
enum TypeEnum{
A("A"),
C("C"),
D("D"),
B("B");
private String s;
private TypeEnum(String s) {
this.s = s;
}
}
public static void main(String agrs[] )
{
Collection<A> stringCollection = new ArrayList<>();
stringCollection.add(new A("A"));
stringCollection.add(new A("D"));
stringCollection.add(new A("D"));
stringCollection.add(new A("C"));
stringCollection.add(new A("D"));
stringCollection.add(new A("B"));
stringCollection.add(new A("A"));
stringCollection.add(new A("A"));
Predicate<A> aPredicate = a -> a.getName() == TypeEnum.A.name();
Predicate<A> cPredicate = a -> a.getName()== TypeEnum.C.name();
Predicate<A> dPredicate = a -> a.getName()== TypeEnum.D.name();
Predicate<A> bPredicate = a -> a.getName()== TypeEnum.B.name();
Predicate<A> fullPredicate = aPredicate.and(cPredicate)
.and(dPredicate).and(bPredicate);
List<A> list= stringCollection.stream().filter(fullPredicate).collect(Collectors.toList());
System.out.println(list);
}
此处输出应为A,A,A,C,D,D,D,B
我想按照上面提到的使用Stream java 8 API按照指定的规则对元素进行排序。 A类是一个在B类中使用的对象,用于将值放入列表中,该类型是A类。最终结果应按照定义的排序规则排序。如果任何人面对同样的问题并为此提供解决方案,那将是非常好的和感恩的。
答案 0 :(得分:2)
您可以按给定列表的位置进行排序:
List<String> order = Arrays.asList("A", "C", "D", "B");
List<A> result = collection.stream()
.sorted(Comparator.comparingInt(a -> order.indexOf(a.getName())))
.collect(Collectors.toList());
这会将未在列表中指定的名称放在前面。您可以使用比较器Comparator.comparingInt(a -> order.indexOf(a.getName())+Integer.MIN_VALUE)
将它们移到最后。
由于重复使用indexOf
,对于较大的order
列表,这不会很好地扩展。
另一种选择是存储桶排序变体:
Map<String, List<A>> m = collection.stream().collect(Collectors.groupingBy(A::getName));
List<A> result = Stream.of("A", "C", "D", "B")
.flatMap(s -> m.getOrDefault(s, Collections.emptyList()).stream())
.collect(Collectors.toList());
此处,未指定的名称根本不会显示在结果中。它会有更好的时间复杂度,但可能暂时消耗更多内存。