Java 是否有等效于 Python 的 ArrayLists.sorted() 方法?



我知道我可以在 Java 的ArrayList上调用Collections.sort(),但我目前正在尝试重载构造函数,在第二个构造函数中,我想调用第一个构造函数。但是,我想传递一个排序列表作为参数之一,但 Java 不允许我在对列表进行排序后调用this()- 它需要this()是第一行。我可以Collections.sort(myList)放入构造函数中,但我不知道此方法是否返回排序列表,但理想情况下,我想返回排序列表而不改变原始列表。

这是我的代码(在一段时间内,您会在学校或大学中找到),包括错误:

public class Period {
private String name;
private LocalDateTime start;
// duration in seconds
private int duration;
private Lecturer lecturer;
private ArrayList<Demonstrator> dems;
private ArrayList<Skill> skills;

public Period(String name, LocalDateTime start, int duration, Lecturer lecturer) {
this.name = name;
this.start = start;
this.duration = duration;
this.lecturer = lecturer;
this.dems = new ArrayList<>();
this.skills = new ArrayList<>();
}

public Period(String name, ArrayList<AvailBlock> blocks, Lecturer lecturer) {
// this line is illegal, but shows you what I'm trying to do.
Collections.sort(blocks);
this(name, blocks.get(0).getStart(), ( blocks.size() * AvailBlock.LENGTH ), lecturer);
}
...
}

AvailBlock类具有作为LocalDateTime对象的开始时间和固定持续时间(当前为 15 分钟)。我试图选择创建一个持续时间以秒为单位的周期,或者只是传入AvailBlock对象列表并让它弄清楚周期何时开始以及应该有多长。

这是AvailBlock类的开始:

public class AvailBlock implements Comparable {

// the start time of the slot
private LocalDateTime start;
// Length of slots in seconds
public static final int LENGTH = 900;

public AvailBlock(LocalDateTime start) {
this.start = start;
}
...
}

创建一个静态工厂方法

正如Mayolo所评论的那样,我会在静态方法而不是构造函数中完成这项工作。最好使构造函数完全简单。

此外,构造函数的第一行必须是对超级构造函数的隐式或显式调用。因此,在调用this( … )Collections.sort之前,我们不能有诸如您对的调用之类的代码。这一定是你在说"//这条线是非法的,但告诉你我想做什么"时提到的问题。这种第一行作为超级构造函数调用的 Java 语言要求是使用静态工厂方法解决问题的另一个原因。

我会根据java.time命名约定from命名该方法。

public static Period from ( … )
{
…
return new Period( … ) ;
}

用法:

Period p = Period.from( … ) ;

复制输入列表

你说:

我可以把 Collections.sort(myList) 放在构造函数中,但我不知道这个方法是否返回排序列表,但理想情况下,我想返回排序列表而不改变原始列表。

在排序之前复制列表。然后,您可以避免更改原始版本。

要制作浅拷贝,可以将任何Collection传递给ArrayList的构造函数

另外,请注意,由于我们制作副本然后排序,因此您的工厂方法可以采用任何类型的List,而不仅仅是ArrayList。实际上,任何类型的Collection都可以接受。

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

List.copyOf

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

<小时 />

record

顺便说一下,您可能会发现添加到Java 16中的记录功能很方便。

记录是编写类的简短方法,该类的主要目的是透明且不可变地传达数据。您只需声明每个成员字段的类型和名称。编译器隐式创建构造函数、getter、equals&hashCodetoString

记录可以携带静态工厂方法,正如我们在解决方案中所需要的那样。

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

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

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

最新更新