• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Rob Spoor
  • Tim Cooke
  • Junilu Lacar
Sheriffs:
  • Henry Wong
  • Liutauras Vilda
  • Jeanne Boyarsky
Saloon Keepers:
  • Jesse Silverman
  • Tim Holloway
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
Bartenders:
  • Al Hobbs
  • Mikalai Zaikin
  • Piet Souris

Bubble Sort. - Syntax compiler Error

 
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello,


I'm trying to implement a bubble sort.

I'm able to create the list from user input.

However when trying to write my bubblesort function. I'm getting some compiler errors that stem from my syntax.

A bit confused as to the errors I'm getting from Line 31 - Line 34. Errors stems from the "list.get(j) and list.get(j+1)"


 
Saloon Keeper
Posts: 8593
71
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
On line 25 you need

Not sure why your getting the error. Whenever you get an error cut and paste the *complete* error message into a post here.
 
Saloon Keeper
Posts: 1328
40
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You are attempting to use Raw Types in your method, which have been generally discouraged since the advent of Generics in Java in 2004.

Additionally, your code is hoping to store int values in the ArrayList, and retrieve them from it, which is not possible.

Changing this:
private static ArrayList bubbleSort(ArrayList list)

to this:
private static ArrayList bubbleSort(ArrayList<Integer> list)

will help a lot.

You should be cautious about using == or != to compare wrapped numeric types for a variety of reasons you could read about here, but < > and <= >= work fine due to auto-unboxing, as long as you don't try to de-reference a null reference anywhere.

The way your code is at the moment, in the line:
               if(list.get(j) > list.get(j+1))

is attempting to use > on references declared (implicitly) as type Object, which is simply not defined in Java.

If you make it an ArrayList<Integer>, the type coming out of it will be Integer, which can be compared to other objects also of type Integer thru (auto-)un-boxing.
 
brian leung
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jesse Silverman wrote:You are attempting to use Raw Types in your method, which have been generally discouraged since the advent of Generics in Java in 2004.

Additionally, your code is hoping to store int values in the ArrayList, and retrieve them from it, which is not possible.

Changing this:
private static ArrayList bubbleSort(ArrayList list)

to this:
private static ArrayList bubbleSort(ArrayList<Integer> list)

will help a lot.

You should be cautious about using == or != to compare wrapped numeric types for a variety of reasons you could read about here, but < > and <= >= work fine due to auto-unboxing, as long as you don't try to de-reference a null reference anywhere.

The way your code is at the moment, in the line:
               if(list.get(j) > list.get(j+1))

is attempting to use > on references declared (implicitly) as type Object, which is simply not defined in Java.

If you make it an ArrayList<Integer>, the type coming out of it will be Integer, which can be compared to other objects also of type Integer thru (auto-)un-boxing.



Hi Jesse,

Thanks, I just figured it out the moment you pasted this!

However that leads me into the next problem

list.get(j) = list.get(j+1);
list.get(j+1) = temp;

In bold, it says variable expected.

Would I have to initiate a new variable inside the if statement?

For example int temp1 = list.get(j) = list.get(j+1); ?
This seems redundant
 
Jesse Silverman
Saloon Keeper
Posts: 1328
40
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You need to read up (at least a little) on the List api:
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html#set(int,E)

"Other Languages" let you use an indexing notation to overwrite values in their equivalent of ArrayList using a convenient:

myNonJavaList[ 5 ] = "not in Java!";

Java takes not allowing Operator Overloading very seriously, so there is no use of [ ] with anything but actual fixed-size Array references.

You have to use .get() and .set( index, value ) for all List types.

I could get geeky and say that .get() doesn't return an Lvalue, but that just means you can't put it on the Left Side of an = assignment (or +=, or *= etc.) for the Beginning Java forum.

If you use Java all the time you get very used to this indeed, if you jump back and forth between Java and Other Languages it is a bit of a culture shock for a minute.

 
Jesse Silverman
Saloon Keeper
Posts: 1328
40
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Also, for the specific case of what you are doing here, you could make use of the following API call that some would recommend to you:

https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Collections.html#swap(java.util.List,int,int)

However, that doesn't get you off the hook for knowing how to overwrite an element in a List at a given index in general, just in this case.
 
Marshal
Posts: 74054
332
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There is no need to enter the size of the List in advance. You can use the Stream‑ing capability of Scanner (Java9+ only).Note that doesn't necessarily produce any particular implementation of List; if you look up Collectors#toList and Stream#collect, one or the other will show an example producing an ArrayList.
 
Jesse Silverman
Saloon Keeper
Posts: 1328
40
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:There is no need to enter the size of the List in advance. You can use the Stream‑ing capability of Scanner (Java9+ only).Note that doesn't necessarily produce any particular implementation of List; if you look up Collectors#toList and Stream#collect, one or the other will show an example producing an ArrayList.



That seems really cool and I am going to endeavor to remember this, but...
how many times does
new Scanner(s)
get called here?
 
Campbell Ritchie
Marshal
Posts: 74054
332
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
One more than there are integers to test for. Once anything non‑int is passed, no more new Scanners are created. Remember you can open a Scanner on a String and you won't need to close it because there aren't any resources. Also the time and memory to create new Scanners will be very slight compared to the time it takes to write numbers to the keyboard.

123 234 345 456 567 678 789 Jesse

Eight tokens: eight Scanner objects. Since they are created as short‑lived local variables in a λ, which escape analysis tells you cannot be accessed from outwith the λ, they will be created on the stack and there will be no need for garbage collection (at least I think so).

jshell> List<Integer> numbers = new Scanner(System.in).tokens().takeWhile(s -> new Scanner(s).hasNextInt()).map(Integer::valueOf).collect(ArrayList::new, List::add, List::addAll);


   123 234 345 456 567 678 789 Jesse
numbers ==> [123, 234, 345, 456, 567, 678, 789]

 
Campbell Ritchie
Marshal
Posts: 74054
332
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Let's correct the indentation:-
 
Jesse Silverman
Saloon Keeper
Posts: 1328
40
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
New technique learned.
Well, semi-learned.
I will remember it is an option but won't fully internalize it until I've used it five or six times.

I don't think it gets the OP off the hook for learning the List api, tho, setting the element at an arbitrary index to an arbitrary value is I daresay more basic than the (very cool) Streams thing you showed.
 
Marshal
Posts: 16597
278
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
1. Many of the problem statements require the program to accept the number of elements to sort as the first input, so ignoring that may not be an option.
2. Assuming #1 is true, then you don't need to use a List. You already know how many elements, so you can just straight up use an array.
3. Also assuming #1, you can use limit() on the Scanner token stream and then just use mapToInt() and toArray()

Edited: IntStream.toArray() returns an int[] not an Integer[]

You can even cheat a little with a prompt:

Lines 6 and 8 is the cheat in the above code. A little clunky but it works if you don't mind the extra prompt at the end.

 
Jesse Silverman
Saloon Keeper
Posts: 1328
40
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Junilu Lacar wrote:1. Many of the problem statements require the program to accept the number of elements to sort as the first input, so ignoring that may not be an option.
2. Assuming #1 is true, then you don't need to use a List. You already know how many elements, so you can just straight up use an array.
3. Also assuming #1, you can use limit() on the Scanner token stream and then just use mapToInt() and toArray()



This goes to what I was beating to death in another thread: on these kinds of problems, you need to write code that works flawlessly for legal input, but generally they don't reward robustness for anything outside what they tell you that you can expect, as good a habit as it is to be in for Real Life.

It still makes sense to put in the equivalent of ASSERT for things that YOU are calculating, and might have messed up, in a way that can save you muchos segundos getting to the final correct answer, but making code that somehow nicely handles if they told you that you are sorting 25 ints and then gives you only 6, for example, not so much.

I agree with what you said in 1., 2. and 3.

In this case, the OP was focused on implementing the Bubble Sort algorithm, I think the third poster in about as many weeks, it must be Bubble Sort Season this time of year, and was tripping over some fairly basic issues with ArrayList<Integer>.

These can be side-stepped for a while by falling back to an array as the data structure.

It is interesting that many generic, language-agnostic problem statements generally DO tell you the number of items to expect as the first input.
Further, they normally show "an answer" in pseudo-code that often contains a line like:
swap( a[i], a[i+1] )

Which is trivial to implement in almost every language I have used except Java, where you need to instead write:
swap( i, i + 1, a )

or write it out in longhand:
int temp = a[i];
a[i] = a[i + 1];
a[i + 1] = temp;


This is something to keep in mind when assisting beginning Java programmers following language-agnostic sorting tutorials.

This and many other (useful to people using HackerRank a lot) information all came out at:
https://coderanch.com/t/744676/java/bubble-sort-passed-test-failed

My "Monk" moment ("Here's how it happened!") came at:

I see the problem now!!!



I believe they asked "an expert" how to write the swap( a[i], a[i+1] ) method, was told "You can't.  You should use an ArrayList<>..." and hijinks ensued.

Before that, we couldn't see why the OP had moved the problem from a simple, easy-to-use array (as shown in their suggested solution from the problem source) to an ArrayList<> despite lack of familiarity with ArrayList<> api, which seemed to be causing the problems.  We also discussed various ways to move a problem between the HackerRank auto-submit/auto-grade platform to a local IDE, which again, can be very useful for any HackerRank problem is "Seriously Hard" for a given individual.

 
Junilu Lacar
Marshal
Posts: 16597
278
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here's my take on why many of the problems we're seeing take the first input as the size of the dataset.

The solutions are tested programmatically and input redirected from some static source through System.in and output redirected to another file, something like this:

This is why using System.in and System.out still works even when the checking is done programmatically.

The first line in the data file will be the size of the data set, for example:

$ cat bubblesort-data.txt
5
11 12 13 14 15
 
brian leung
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jesse Silverman wrote:You need to read up (at least a little) on the List api:
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/List.html#set(int,E)

"Other Languages" let you use an indexing notation to overwrite values in their equivalent of ArrayList using a convenient:

myNonJavaList[ 5 ] = "not in Java!";

Java takes not allowing Operator Overloading very seriously, so there is no use of [ ] with anything but actual fixed-size Array references.

You have to use .get() and .set( index, value ) for all List types.

I could get geeky and say that .get() doesn't return an Lvalue, but that just means you can't put it on the Left Side of an = assignment (or +=, or *= etc.) for the Beginning Java forum.

If you use Java all the time you get very used to this indeed, if you jump back and forth between Java and Other Languages it is a bit of a culture shock for a minute.



I've tried to read through the remaining posts on this thread, however i'm a bit lost with the streaming input/output. I'm simply trying to write a program where I can sort an arraylist of whatever size and elements of my choosing.

I've tried to read through the List Api documents on Oracle, but am still stuck unfortunately.



I've made the following changes on Line 13 and 14. However, getting a warning when calling the .equals() function. When I run my program, it doesn't show the output. I'm not surprised. Would you be able to point me in the direction of my mistake?
 
Carey Brown
Saloon Keeper
Posts: 8593
71
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Read the Java doc on List#set.

You are putting in a get() call where an index is  needed.
 
Carey Brown
Saloon Keeper
Posts: 8593
71
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
"equals()" is used for comparison, not for assignment.
 
Carey Brown
Saloon Keeper
Posts: 8593
71
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Just a reminder that this is what you were trying to fix. You have to change the get()s on the left side of the "=" to a call to set().

 
Carey Brown
Saloon Keeper
Posts: 8593
71
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

 
Junilu Lacar
Marshal
Posts: 16597
278
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

brian leung wrote:
I've tried to read through the remaining posts on this thread, however i'm a bit lost with the streaming input/output. I'm simply trying to write a program where I can sort an arraylist of whatever size and elements of my choosing.


The problems are:

1. You are confused about how to use the List API - you are, in my opinion, making things unnecessarily harder for yourself by using an ArrayList instead of just a plain old array of int. The get() method is used to read a value from the ArrayList, the set() method is used to save a value in the ArrayList. Somehow, you're confused as to when to use one or the other.

2. As I said before, since you are prompting for the number of elements to sort, you can use an int[] of the appropriate size and do simple assignment with the = operator and comparisons with the == operator. You are also somehow confused as to when to use equals() as evidenced by this line:

This line of code has no effect whatsoever in your program, basically a do-nothing statement, but you seem to think it assigns the value of temp to temp1. It doesn't.
 
Junilu Lacar
Marshal
Posts: 16597
278
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

brian leung wrote:i'm a bit lost with the streaming input/output.


Ignore that stuff if it confuses you then. All that's about is getting the values to sort collected in a List. You can do that just the way you originally showed it. People around here are just a little enamored with streams right now so that's why you're seeing stream-based suggestions for how to do things.

But if your objective was to just sort the values, you could easily do that by adding sorted() to what I suggested earlier:


But simply sorting the values is not the objective; specifically, you want to implement the bubble sort algorithm so doing the above is cheating.
 
Campbell Ritchie
Marshal
Posts: 74054
332
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Junilu Lacar wrote:. . . you want to implement the bubble sort algorithm so doing the above is cheating.

Also the sorted() method probably uses merge sort (or a special kind of merge sort), so it wouldn't use bubble sort at all.
 
Junilu Lacar
Marshal
Posts: 16597
278
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Also the sorted() method probably uses merge sort (or a special kind of merge sort), so it wouldn't use bubble sort at all.


I followed the white rabbit and ended up in Arrays.sort() which, at least in the Java source code I looked at, makes a call to DualPivotQuickSort, whatever that is.
 
Campbell Ritchie
Marshal
Posts: 74054
332
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If I remember correctly, sorting arrays of primitives uses a kind of quicksort and sorting arrays of reference types uses TimSort which is a kind of merge sort. Merge sort might not be as fast as quicksort, but its speed is more consistent, and more important, it is “stable”, so it won't swap two elements returning 0 from Comparator#compare() or (Comparable)#compareTo(). TimSort seems to allow much faster execution when the array is mostly sorted already.
 
Jesse Silverman
Saloon Keeper
Posts: 1328
40
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think that for what they were trying to focus on, implementing the Bubble Sort algorithm, I am with Junilu that the OP should be using an Array, and getting clear on the difference between = and == in Java.

Basic usage of ArrayList<T> is pretty basic, and they should come back to this sooner, rather than later, but probably not right now.
When they do, they should probably go thru the tutorials, meant to introduce the usage, rather than the JavaDocs which are extremely appropriate when you are confused about the details of some exotic method in the API, but not really intended to teach the basics to beginners.

Streams are Awesome, and while we may now consider them part of Core Java or even Basic Java, I am not sure it is helpful to be throwing them into the mix when someone is still unsure of True Basics like = versus == versus .equals(), LValue versus RValue semantics in Java (they don't need to learn that term but need to understand its implications in how to write expressions) and ArrayList basics.
The OP should probably ignore Streams for now, as awesome as they will later make their programming down the road.

The way we teach Intro to Java may well be evolving, and all of the people supplying suggestions are aware of this, but for now I would say this is still the order we should be helping the OP (and others with similar levels of Java facility in the near future).

I took a very Traditional approach, where I made sure I understood Arrays first, then moved on to the Collections Framework, then further on to Lambdas, Method References and Streams, and do not regret it.
 
Junilu Lacar
Marshal
Posts: 16597
278
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

brian leung wrote:When I run my program, it doesn't show the output. I'm not surprised. Would you be able to point me in the direction of my mistake?


The biggest problem is that what you've written is NOT even remotely close to being an implementation of the bubble sort algorithm.

Here's what Wikipedia has:

Notice that there's only one loop, not two nested loops. Note the swapped variable, which you don't have. Also note that the pseudocode assumes an array data structure and as I said, your use of an ArrayList instead just complicates things for yourself since you're confused by the List API.

EDIT: restoring deleted part to add context to Carey's response below.
 
Carey Brown
Saloon Keeper
Posts: 8593
71
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There's a "for" loop and a "repeat-until" loop. NEVER MIND - You edited your post. Tsk.
 
brian leung
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Junilu Lacar wrote:

brian leung wrote:
I've tried to read through the remaining posts on this thread, however i'm a bit lost with the streaming input/output. I'm simply trying to write a program where I can sort an arraylist of whatever size and elements of my choosing.


The problems are:

1. You are confused about how to use the List API - you are, in my opinion, making things unnecessarily harder for yourself by using an ArrayList instead of just a plain old array of int. The get() method is used to read a value from the ArrayList, the set() method is used to save a value in the ArrayList. Somehow, you're confused as to when to use one or the other.

2. As I said before, since you are prompting for the number of elements to sort, you can use an int[] of the appropriate size and do simple assignment with the = operator and comparisons with the == operator. You are also somehow confused as to when to use equals() as evidenced by this line:

This line of code has no effect whatsoever in your program, basically a do-nothing statement, but you seem to think it assigns the value of temp to temp1. It doesn't.



Ah, I understand.

My lack of experience was what caused me to use the array list in the first place, thus making things harder. Now I understand why it was better to just use an array. I had thought that because we were getting input from the user as to what size array they would like, I thought using a fixed array wouldn't work, and would require a list collection instead. Total elementary mistake.

Thanks for your patience, my program is working now!
 
brian leung
Ranch Hand
Posts: 30
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


Final Code.
 
Jesse Silverman
Saloon Keeper
Posts: 1328
40
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey Brian!

That works, and addresses many different individual difficulties that were discussed in this long and wide-ranging thread, which touched on many topics that will be important later, but perhaps not now.

Some folks 'round these parts are darn near allergic to seeing static methods, but whatever culture I came out of is fine with that.

The use of the static data member is not illegal or that bad either, but there were some aspects of your solution that weren't necessary if you went that route, or were able to be tweaked just a tiny bit to make that static data member removable.

I might have written the same code a bit more like this (changes left in as comments to be more noticeable):



But this doesn't change the algorithm one bit, and that algorithm (the first sort I ever learned, and for a long time the only one I knew) is correctly implemented.
I always feel embarrassed by that, but on a bit of reflection, our memory sizes were so tiny (I was very proud to have 48k, instead of 16k, 8k  or even 3k like most of my friends) that we didn't even have enough memory for the algorithm choice to make much difference!

The stuff you learned here will mean you have almost no new Java to learn on the next few kinds of sort algorithm problems you may do.
The language tricks are out of the way.
 
When people don’t understand what you are doing they call you crazy. But this tiny ad just doesn't care:
Thread Boost feature
https://coderanch.com/t/674455/Thread-Boost-feature
reply
    Bookmark Topic Watch Topic
  • New Topic