对于ArrayList,java是否有与python的list.sorted()方法等效的方法?

r1zhe5dt  于 2021-08-25  发布在  Java
关注(0)|答案(2)|浏览(443)

我知道我可以打电话 Collections.sort()ArrayList 在java中,但我目前正在尝试重载构造函数,在第二个构造函数中,我想调用第一个构造函数。但是,我想将排序列表作为参数之一传递,但java不允许我调用 this() 对列表进行排序后-需要 this() 第一行。我可以把 Collections.sort(myList) 在构造函数中,但我不知道该方法是否返回排序列表,但理想情况下,我希望返回排序列表而不改变原始列表。
这是我的代码(适用于学校或大学的一段时间),包括错误:

  1. public class Period {
  2. private String name;
  3. private LocalDateTime start;
  4. // duration in seconds
  5. private int duration;
  6. private Lecturer lecturer;
  7. private ArrayList<Demonstrator> dems;
  8. private ArrayList<Skill> skills;
  9. public Period(String name, LocalDateTime start, int duration, Lecturer lecturer) {
  10. this.name = name;
  11. this.start = start;
  12. this.duration = duration;
  13. this.lecturer = lecturer;
  14. this.dems = new ArrayList<>();
  15. this.skills = new ArrayList<>();
  16. }
  17. public Period(String name, ArrayList<AvailBlock> blocks, Lecturer lecturer) {
  18. // this line is illegal, but shows you what I'm trying to do.
  19. Collections.sort(blocks);
  20. this(name, blocks.get(0).getStart(), ( blocks.size() * AvailBlock.LENGTH ), lecturer);
  21. }
  22. ...
  23. }

这个 AvailBlock 类有一个开始时间作为 LocalDateTime 对象和固定的持续时间(当前为15分钟)。我正在尝试创建一个持续时间为秒的句点,或者只是传递一个句点列表 AvailBlock 对象,并让它计算周期何时开始以及应该持续多长时间。
这是本书的开头 AvailBlock 类别:

  1. public class AvailBlock implements Comparable {
  2. // the start time of the slot
  3. private LocalDateTime start;
  4. // Length of slots in seconds
  5. public static final int LENGTH = 900;
  6. public AvailBlock(LocalDateTime start) {
  7. this.start = start;
  8. }
  9. ...
  10. }
bq8i3lrv

bq8i3lrv1#

制作一个静态工厂方法

正如mayolo所评论的,我将在静态方法中而不是在构造函数中完成这项工作。最好保持构造函数完全简单。
此外,构造函数的第一行必须是对超级构造函数的隐式或显式调用。所以我们不能有像您对的调用这样的代码 Collections.sort 在打电话给 this( … ) . 这一定是你在说“//这行是非法的,但向你展示了我试图做的事情”时提到的问题。第一行作为超级构造函数调用的java语言要求是使用静态工厂方法解决问题的另一个原因。
我将命名该方法 from 按照java.time命名约定。

  1. public static Period from ( )
  2. {
  3. return new Period( ) ;
  4. }

用法:

  1. Period p = Period.from( ) ;

复制输入列表

你说:
我可以将collections.sort(mylist)放在构造函数中,但我不知道这个方法是否返回排序列表,但理想情况下,我希望返回排序列表而不改变原始列表。
排序前,复制一份列表。然后你就可以避免对原作进行变异。
要制作浅拷贝,您可以传递任何 CollectionArrayList .
另外,请注意,由于我们制作了一个副本,然后进行排序,所以您的工厂方法可以采用任何类型的 List ,不只是 ArrayList . 事实上,任何一种 Collection 可以接受。

  1. public static Period from ( String name, Collection< AvailBlock > blocks, Lecturer lecturer )
  2. {
  3. ArrayList< AvailBlock > blocksSorted = new ArrayList<>( blocks ) ;
  4. Collections.sort( blocksSorted );
  5. return new Period( name, blocksSorted.get(0).getStart(), ( blocks.size() * AvailBlock.LENGTH ), lecturer ) ;
  6. }

list.copyof

如果您想要不可修改的副本,请将列表传递给 List.copyOf .

记录

顺便说一下,您可能会发现添加到Java16中的记录功能非常方便。
记录是编写类的一种简单方法,其主要目的是以透明和不变的方式传输数据。您只需要声明每个成员字段的类型和名称。编译器隐式创建构造函数getter, equals & hashCode ,及 toString .
记录可以携带静态工厂方法,正如我们在解决方案中需要的那样。

展开查看全部
8nuwlpux

8nuwlpux2#

我会回应其他人关于在构造函数中不要做太多的评论。但是,如果您确实希望在不改变原始列表的情况下进行内联排序,那么流似乎是最自然的方式。您可以非常轻松地进行排序,而无需更改原始列表:

  1. blocks.stream().sorted().collect(Collectors.toList())

(…它将返回一个排序列表,您可以内联使用该列表,也可以将其分配给变量。)

相关问题