Java 番石榴能保证顺序吗?

Java 番石榴能保证顺序吗?,java,guava,Java,Guava,在转换过程中,我可以依赖顺序吗 public class DtoFunc implements Function<Entity,DTO>{ Entity previousEntity; @Override public DTO apply(Entity entity){ DTO dto = new DTO(); // do transforming previousEntity = entity;

在转换过程中,我可以依赖顺序吗

public class DtoFunc implements Function<Entity,DTO>{

    Entity previousEntity;

    @Override
    public DTO apply(Entity entity){
       DTO dto = new DTO();
       // do transforming

       previousEntity = entity;
       return dto;
    }
}
公共类DtoFunc实现函数{
实体优先实体;
@凌驾
要应用的公共数据传输(实体){
DTO DTO=新的DTO();
//改造
先前实体=实体;
返回dto;
}
}
正如您所看到的,我将状态存储在函数中,并且我依赖于当我调用Lists.transform(entityList,new DtoFunc())时,它将进行必然的转换 .它是按顺序转换的吗??我可以信赖它吗

正确答案:转换顺序取决于对转换列表的访问,因为转换是惰性的。函数必须是无状态的,因为Guava不是线程安全的。

来自Javadocs:

返回的列表是
fromList
的转换视图;对列表中
的更改将反映在返回的列表中,反之亦然

虽然没有明确说明,但我认为这一点和其余的描述暗示着秩序将得到保留

编辑:这里的关键字是查看:返回的列表由原始列表支持,文档还解释了在需要时延迟应用该功能。是的,顺序是一样的。根据您想对列表做什么,Guava甚至建议在某些情况下,创建一个真实的副本而不是转换视图可能更明智。

来自JavaDoc:

该函数是惰性应用的,在需要时调用

即,如果您这样做:

List<Foo> fooList = newArrayList<Foo>();
// ...
List<Bar> barList = Lists.transform(fooArrayList, fooToBarFunction);
barList.get(5);
此调用将通过从元素0迭代到元素5来访问索引为5的元素,可能会对其间的每个元素应用转换函数


因此,转换的顺序无法保证。但是,如果您可以控制返回列表的访问顺序,并且如果源列表的类型为
RandomAccess
,则
fooToBarFunction
的调用顺序与结果列表上的调用顺序完全相同。从文档中可以看出,当您访问返回的列表时,函数会被延迟应用,并且如果源列表执行随机访问,则保证返回的列表会实现随机访问。

明确说明了这一点。如果返回的列表是转换视图,则元素顺序必须保持不变。因为顺序没有被转换。只有元素。@RenéLink谢谢,我是在仔细考虑了机制和文字之后才意识到这一点的。另一个关键词是
List
,它被明确定义为有序。正确答案是-是的,我可以依赖oreder?Sorrry,但“转换的顺序没有保证。”以及“与结果列表上的调用顺序完全相同“没有冲突吗??我没有得到正确的答案,我能依赖顺序吗?@Playmate:这里的关键字是保证的-番石榴没有对顺序做出任何保证,但由于转换函数的惰性,它恰好是相同的顺序。天哪,番石榴不保证,但恰好是相同的顺序?你在开玩笑吧?对不起,我不明白为什么Guava不能保证但转换函数恰好是相同的顺序,我发现这些短语是矛盾的。@Playmate:如果你控制对结果列表的访问,你可以依赖顺序。因此,如果使用迭代器,每次迭代一个,那么调用函数的顺序就是元素的顺序。但是,如果您使用remove(Object),那么它可能会迭代,直到找到匹配的条目为止,随后的remove(Object)调用可能会重新启动或执行不同的操作。存储前一个实体以处理下一个实体是一种代码味道,可能表明for循环更好。请看@Etienne Neveu中的注意事项:我已经阅读了链接,但我没有找到关于无状态的smth?事实上,wiki没有提到“状态”。我指的是Guava函数式习惯用法背后的一般哲学:“过度使用Guava函数式编程习惯用法会导致冗长、混乱、不可读和低效的代码。”。在您的例子中,使用有状态函数是令人困惑的,并且可能会导致奇怪的错误,因为list#transform()会延迟地应用它们(如答案中所解释的),因此for循环可能更可取。这里有一个指向Guava团队成员的链接,他说函数不应该有副作用(例如无状态):我使用列表作为列表。newArrayList(list.transform(myList,myFunc));-不要偷懒<代码>函数
应以无状态方式使用。如果需要状态,则不应使用它。
List<Foo> fooList = newLinkedList<Foo>();
// ...
List<Bar> barList = Lists.transform(fooArrayList, fooToBarFunction);
barList.get(5);