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

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

我知道我可以打电话 Collections.sort()ArrayList 在java中,但我目前正在尝试重载构造函数,在第二个构造函数中,我想调用第一个构造函数。但是,我想将排序列表作为参数之一传递,但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;
    }
    ...
}
bq8i3lrv

bq8i3lrv1#

制作一个静态工厂方法

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

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

用法:

Period p = Period.from( … ) ;

复制输入列表

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

记录

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

8nuwlpux

8nuwlpux2#

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

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

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

相关问题