相关疑难解决方法(0)

Java 8属性不同

在Java 8中,如何Stream通过检查每个对象的属性的清晰度来使用API 过滤集合?

例如,我有一个Person对象列表,我想删除具有相同名称的人,

persons.stream().distinct();
Run Code Online (Sandbox Code Playgroud)

将使用Person对象的默认相等检查,所以我需要像,

persons.stream().distinct(p -> p.getName());
Run Code Online (Sandbox Code Playgroud)

不幸的是,该distinct()方法没有这种过载.如果不修改类中的相等性检查,Person是否可以简洁地执行此操作?

java collections java-8 java-stream

406
推荐指数
20
解决办法
24万
查看次数

Java8 Streams - 删除具有Stream Distinct的重复项

我有一个流如:

Arrays.stream(new String[]{"matt", "jason", "michael"});
Run Code Online (Sandbox Code Playgroud)

我想删除以相同字母开头的名称,以便只留下以该字母开头的一个名称(无关紧要).

我试图了解该distinct()方法的工作原理.我在文档中读到它基于对象的"等于"方法.但是,当我尝试包装String时,我注意到从不调用equals方法,也没有删除任何内容.这里有什么我想念的吗?

包装类:

static class Wrp {
    String test;
    Wrp(String s){
        this.test = s;
    }
    @Override
    public boolean equals(Object other){
        return this.test.charAt(0) == ((Wrp) other).test.charAt(0);
    }
}
Run Code Online (Sandbox Code Playgroud)

还有一些简单的代码:

public static void main(String[] args) {
    Arrays.stream(new String[]{"matt", "jason", "michael"})
    .map(Wrp::new)
    .distinct()
    .map(wrp -> wrp.test)
    .forEach(System.out::println);
}
Run Code Online (Sandbox Code Playgroud)

java string java-8 java-stream

27
推荐指数
2
解决办法
6万
查看次数

合并Java 8中的两个对象列表

我有一个Parent具有20个属性的Java类(attrib1, attrib2 .. attrib20)及其相应的getter和setter.我还有两个Parent对象列表:list1list2.

现在我想合并两个列表并避免基于attrib1和的重复对象attrib2.

使用Java 8:

List<Parent> result = Stream.concat(list1.stream(), list2.stream())
                .distinct()
                .collect(Collectors.toList());   
Run Code Online (Sandbox Code Playgroud)

但是我必须在哪个地方指定属性?我应该覆盖hashCodeequals方法吗?

java java-8 java-stream

27
推荐指数
1
解决办法
4万
查看次数

Java Streams:如何做一个有效的"独特和排序"?

让我们假设我有一个Stream<T>并且想要只获得不同的元素并进行排序.

天真的方法是做到以下几点:

Stream.of(...)
    .sorted()
    .distinct()
Run Code Online (Sandbox Code Playgroud)

或者,也许相反:

Stream.of(...)
    .distinct()
    .sorted()
Run Code Online (Sandbox Code Playgroud)

由于JDK的源代码无法实现这两者的实现,我只是想知道可能的内存消耗和性能影响.

或者编写我自己的过滤器会更有效率如下?

Stream.of(...)
    .sorted()
    .filter(noAdjacentDuplicatesFilter())

public static Predicate<Object> noAdjacentDuplicatesFilter() {
    final Object[] previousValue = {new Object()};

    return value -> {
        final boolean takeValue = !Objects.equals(previousValue[0], value);
        previousValue[0] = value;
        return takeValue;
    };
}
Run Code Online (Sandbox Code Playgroud)

java performance java-8 java-stream

21
推荐指数
1
解决办法
4478
查看次数

java 8如何在多个属性上获取不同的列表

如何从对象列表中获得不同的(基于两个属性的不同)列表.例如,让我们有属性名称和价格的对象列表.现在我如何获得具有不同名称或价格的列表.
假设

list<xyz> l1 = getlist(); // getlist will return the list.
Run Code Online (Sandbox Code Playgroud)

现在让l1具有以下属性(名称,价格): -
n1,p1
n1,p2
n2,p1
n2,p3

现在在过滤器之后,列表应为-n1
,p1
n2,p3

我试着像这样解决 -

public List<xyz> getFilteredList(List<xyz> l1) {

        return l1
                .stream()
                .filter(distinctByKey(xyz::getName))
                .filter(distinctByKey(xyz::getPrice))
                .collect(Collectors.toList());
    }

    private static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
        Map<Object,Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }
Run Code Online (Sandbox Code Playgroud)

现在的问题是当我对名称进行过滤时,列表返回将是 -
n1,p1
n2,p1

然后它将在价格上运行过滤器返回 -
n1,p1

这不是预期的结果.

java lambda distinct-values java-8 java-stream

8
推荐指数
2
解决办法
2万
查看次数

Predicate如何在Java 8中维护状态

我正在查看此代码并尝试理解以下代码.

复制自Stuart Marks的回答

public static <T> Predicate<T> distinctByKey(Function<? super T,Object> keyExtractor) {
    Map<Object,Boolean> seen = new ConcurrentHashMap<>();
    return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}

BigDecimal totalShare = orders.stream()
    .filter(distinctByKey(o -> o.getCompany().getId()))
    .map(Order::getShare)
    .reduce(BigDecimal.ZERO, BigDecimal::add);
Run Code Online (Sandbox Code Playgroud)

我的问题是每次调用distinctByKey并生成新的ConcurrentHashMap.如何使用新的ConcurrentHashMap <>()来维护状态;

java-8 java-stream

6
推荐指数
2
解决办法
1034
查看次数

等效于使用自定义比较器进行流式处理

如果我有以下列表:

List<String> list = Arrays.asList("hello", "world", "hello");
Run Code Online (Sandbox Code Playgroud)

我应用以下(Java8):

list.stream().distinct().collect(Collectors.toString());
Run Code Online (Sandbox Code Playgroud)

然后我会得到一个包含“hello”和“world”的列表。

但是,就我而言,我有一个类型列表(来自外部 api),我想在其中“绕过”equals 方法,最好使用比较器,因为它没有涵盖我需要的内容。

假设这个类看起来像这样:

public class Point {
    float x;
    float y;
    //getters and setters omitted
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我希望将涵盖特定标准的两点定义为相等,例如 (30, 20) 和 (30.0001, 19.999)。

自定义比较器可以做到这一点,但我发现没有 API 可以执行 Java8 Stream 中的 distinct() 功能,而是使用比较器(或类似模式)。

有什么想法吗?我知道我可以编写这样的函数,但我更喜欢使用现有 apis 的优雅方式......我对外部库没有限制(番石榴、apache-commons 等,如果他们有一种舒适的方式,欢迎使用)我需要的)。

java collections java-stream

5
推荐指数
1
解决办法
2888
查看次数

java 8流:复杂的流处理

我想创建一个对流执行一些复杂操作的方法(例如替换第 7 个元素, 删除最后一个元素, 删除相邻的重复项等)而不缓存整个流。

但是什么流 api 让我插入这个方法?我是否必须创建自己的收集器,以便在收集时将项目发送到其他流?但这会改变数据流的方向,从拉到推,对吧?

这种方法的可能签名是什么?

Stream<T> process(Stream<T> in)
Run Code Online (Sandbox Code Playgroud)

可能是不可能的(在单线程代码中),因为只有在收集整个输入流后才能返回结果

另一个想法:

void process(Stream<T> in, Stream<T> out)
Run Code Online (Sandbox Code Playgroud)

似乎也有点缺陷,因为 java 不允许发出将项目插入现有流(作为out参数提供)。

那么我如何在java中进行一些复杂的流处理?

java java-8 java-stream

1
推荐指数
1
解决办法
1727
查看次数