切换对象之间的关联方向

时间:2018-11-07 23:27:56

标签: java java-8 java-stream

说我有一个课程foo

class foo {
    String someString;
    List<String> someList;
}

如果我有一个foo的列表,有没有一种方法可以创建一个新的列表/数组/任何foo的列表,基本上是someString和{ {1}}个值是否被重新映射?例如:

someList

将成为

arr1: [
    foo {
        someString: 'test1',
        someList: ['a', 'b']
    },
    foo {
        someString: 'test2',
        someList: ['b', 'c']
    }
]

现在,我有一个嵌套循环,它为每个foo遍历arr2: [ foo { someString: 'a', someList: ['test1'] }, foo { someString: 'b', someList: ['test1', 'test2'] }, foo { someString: 'c', someList: ['test2'] }, ] 的每个元素,并将它们编译成一个映射,其中键是someList的值,并且该值是一组来自someList值所在的foo的someString值。然后对条目集进行映射,以将键和值作为构造函数参数传递给它,将其转换为新的foos。

someList

这看起来不错,但它并不是世界上最漂亮的,所以我想知道是否还有另一种方法可以做到这一点。

3 个答案:

答案 0 :(得分:3)

首先使用地图翻转对象:

Map<String, Set<String>> map = new LinkedHashMap<>();
arr1.forEach(foo -> 
        foo.someList.forEach(s -> 
                map.computeIfAbsent(
                    s, 
                    k -> new LinkedHashSet<>())
                .add(foo.someString)));

然后从地图创建foo对象:

List<foo> result = new ArrayList<>();
map.forEach((k, v) -> list.add(new foo(k, new ArrayList<>(v))));

这假定您具有适当的构造函数。

答案 1 :(得分:0)

为什么不这样在嵌套循环中创建foo对象?

Map<String, foo> myMap;

 for(foo f : arr1) {
  for(String s : f.someList) {
    foo myFoo= myMap.get(s);
    if(mySet == null) {
        myFoo= new foo(s, new ArrayList<String>);
        myMap.put(s, myFoo);

    } 
    myFoo.somelist.add(f.someString);
  }
}

答案 2 :(得分:0)

这是带有Guava库的Java 8上的示例:

private static Function<Foo,Set<Foo>> fooStream(final Map<String,Foo> map){
        return foo -> foo.getSomeList().stream()
                .map(createNewFoo(foo.getSomeString(),map)).collect(Collectors.toSet());

    }

    private static Function<String,Foo> createNewFoo(final String someString,final Map<String,Foo> map){
        return s->{
            if(Objects.nonNull(map.get(s))){
                map.get(s).getSomeList().add(someString);
                return map.get(s);
            }
            return createNewFoo(s,someString,map);
        };
    }

    private static Foo createNewFoo(final String someListValue , final String someString,final Map<String,Foo> map){
        final Foo foo = new Foo(someListValue,Lists.newArrayList(someString));
        map.put(someListValue,foo);
        return foo;
    }

这里是如何在main方法中调用它的方法:

final Map<String, Foo> myMap = Maps.newHashMap(); 
final Foo foo1 = new Foo("test1",Arrays.asList("A","B")); 
final Foo foo2 = new Foo("test2",Arrays.asList("B","C")); 
final List<Foo> foos = Arrays.asList(foo1,foo2); 
final Set<Foo> fooSet = foos.stream()
.map(fooStream(myMap)) 
.flatMap(Set::stream).collect(Collectors.toSet());

Foo类在哪里:

public class Foo {
    private String someString;
    private List<String> someList;

    public Foo(String someString, List<String> someList) {
        this.someString = someString;
        this.someList = someList;
    }
//getters and setters
}