如何在java 8

时间:2018-06-04 11:13:26

标签: java java-8

您假设有一个对象列表。该列表按该对象的一个​​或多个字段排序。所以根据排序列表,我想用增量值设置该对象的字段 为澄清,请注意以下示例:

public class ObjectTest {
   int id;
   int userId;
   int code;
}

如上所述ObjectTest,任何用户都有自己的代码 有一个ObjectTest列表。

List<ObjectTest> objTests;

分类:

objTests.sort(Comparator.comparing(DataSet::getUserId).thenComparing(DataSet::getCode));

因此,在按userId和代码排序之后,我想将值从1设置为任何用户拥有自己的代码。当userId发生变化时,增量值将再次重置为1。

如果有以下ObjectTest集合。

    id     userId    code
--------------------------------
             100     5
             200     6
             100     7
             200     9
             200     10
             100     2

在解释了上述场景之后,以下集合将是:

id      userId     code
1        100        2
2        100        5
3        100        7
1        200        6
2        200        9
3        200        10

是否可以在java中使用lambda表达式

4 个答案:

答案 0 :(得分:4)

有些事情应该有效:

List<ObjectTest> resultSet = 
objTests.stream()
        .sorted(Comparator.comparing(ObjectTest::getUserId).thenComparing(ObjectTest::getCode))
        .collect(Collectors.groupingBy(ObjectTest::getUserId, LinkedHashMap::new, Collectors.toList()))
        .values()
        .stream()
        .map(e -> {
            IntStream.range(0, e.size())
                    .forEach(i -> e.get(i).setId(i + 1));
            return e;
        })
        .flatMap(Collection::stream)
        .collect(Collectors.toList());

注意,我还没有编译这段代码。

答案 1 :(得分:1)

可能有可能,但您很可能无法使用流API 解决此问题。

原因是流API 函数式编程的Javas实现,FP中的一个关键假设是对象(或更好的任何数据)都有彼此没有关系 没有任何功能可以更改输入数据的状态

因此,您的要求会因FPs关键假设而中断。

  

你有什么想法来实现我的目标? - reza ramezani matin

按用户ID分组对象:

Map<Integer,ObjectTest> userIdMap= objTests.stream()
    .collect(Collectors.groupingBy(
                           ot ->ot.userId , ot ->ot
                    ));

枚举传统循环:

for(Collection<ObjectTest> ol : userIdMap.values()){
   objectList = new ArrayList(ol);
   Colections.sort(ol, /* comparator here*/);
   for(int id = 0; id < ol.size();)
      objectList.get(id).id=++id;
}

答案 2 :(得分:1)

您可以为范围内的原子整数对象创建userId的映射,然后遍历排序列表以设置ID。

Map<Integer, AtomicInteger> userIds = 
        objTests.stream()
        .map(obj -> Integer.valueOf(obj.getUserId()))
        .distinct()
        .collect(Collectors.toMap(Function.identity(), 
                 (id) -> new AtomicInteger(1)));

上面的地图包含每个唯一userId的原子整数对象。

objTests.stream()
        .forEach(obj -> obj.setId(userIds.get(obj.getUserId())
                                   .getAndIncrement()));

这最后一个代码只是遍历排序列表,然后从与实例上的用户ID关联的原子整数中分配id读取。

答案 3 :(得分:0)

我同意@Varvarigos Emmanouil,有时没有Stream API会更容易。

Collections.sort(list, Comparator.comparing(ObjectTest::getUserId).thenComparing(ObjectTest::getCode));
int userId = list.get(0).userId;
int index = 0;
for (ObjectTest objectTest:list){
     if (userId != objectTest.userId){
          index = 0;
          userId = objectTest.userId;
     }
      objectTest.setId(++index);
}