Here record is an ArrayList of objects of the type Employee. I am trying to sort the ArrayList based on the employeeName attribute. Unfortunately, it gives unwanted results.
public void sortByName(){
for(int i = 0; i < SalesDataManager.N; i++){
for(int j = i+1; j < SalesDataManager.N; j++){
if(record.get(i).getEmployeeName().compareToIgnoreCase(record.get(j).getEmployeeName()) > 0){
Employee etemp = record.get(i);
record.add(i,record.get(j));
record.add(j,etemp);
}
}
}
displayAllRecords();
}
I have gone through other posts in stackoverflow regarding this topic and found out that most of the post suggest this same way.Am I doing something wrong here?
Thanks in advance!
You are iterating the record list and according to some condition determining where to add the current element. However, you aren't emptying the list first, so this approach will inevitably lead to duplications.
Java, luckily, has a built it mechanism for such sorting - you just need to implement a Comparator:
public class EmployeeNameComparator implements Comparator<Emplyoee> {
#Override
public int compare (Employee a, Employee b) {
return a.getEmployeeName().compareToIgnoreCase(b.getEmployeeName());
}
And then just use it:
Collections.sort (record, new EmployeeNameComparator());
If you're using Java 8, you could also use the new cleaner syntax:
Collections.sort
(record, (a, b) -> a.getEmployeeName().compareToIgnoreCase(b.getEmployeeName());
#Howard Wang and Mureinik, you guys were right. The add(index,object) method added the object to the index and was right-shifting the already existing object, instead of replacing it, which was what I was intending to achieve. So, adding record.remove(i+1); and record.remove(j+1); to the code did the trick!
public void sortBySales()
{
for(int i = 0; i < SalesDataManager.N; i++)
{
for(int j = i+1; j < SalesDataManager.N; j++)
{
if(record.get(i).getEmployeeSales() > record.get(j).getEmployeeSales())
{
Employee etemp = record.get(i);
record.add(i,record.get(j));
record.remove(i+1);
record.add(j,etemp);
record.remove(j+1);
}
}
}
}
Related
I am trying to develop a method which receives a List of ArrayList and classify the array list inside it based on the object value. Then, return array list that contains the objects have 1 in their FirstChoice.
the data structure in my code is that
the List has n number of ArrayList, the ArrayList has 24 objects. each object has 3 elements and FirstChoice is one of these elements.
The problem of my code is the output not as i expect , it seems to be just stick with one value and repeat it for the whole list. could you please help me to fix that
ArrayList<HH> TestMethods(List<ArrayList<HH>> s) {
ArrayList<HH> scenario = new ArrayList<HH>();
for (ArrayList<HH> d : s) {
for (int i = 0; i < d.size(); i++) {
if (s.get(i).get(i).FirstChoice == 1) {
scenario.add(s.get(i).get(i));
}
}
}
return scenario;
}
The problem in your code is that when you are looping over the list s, you are actually never using the current element d.
Some other comments on your code:
Prefer returning a List instead of an ArrayList.
Name your methods and variables according to Java naming conventions (testMethods instead of TestMethods, firstChoice instead of FirstChoice)
Be consistent in the way you write loops: use foreach or an index but keep to the same style.
List<HH> testMethods(List<ArrayList<HH>> s) {
List<HH> scenario = new ArrayList<HH>();
for (ArrayList<HH> d : s) {
for (HH hh : d) {
if (hh.firstChoice == 1) {
scenario.add(hh);
}
}
}
return scenario;
}
Your mistakes are on these lines if (s.get(i).get(i).FirstChoice == 1) { and scenario.add(s.get(i).get(i)); as you aren't actually user inner list d.
You're referencing the i'th element of the i'th list of s, when I think you want the i'th element of d where d is a list from s.
ArrayList<HH> TestMethods(List<ArrayList<HH>> s) {
ArrayList<HH> scenario = new ArrayList<HH>();
for (ArrayList<HH> d : s) {
for (int i = 0; i < d.size(); i++) {
int item = d.get(i).FirstChoice;
if (item == 1) {
scenario.add(item);
}
}
}
return scenario;
}
I have an array of contacts like so :
public class Application {
private Scanner input;
private Contact[] contacts;
private int ArrayNum;
public Application() {
input = new Scanner(System.in);
contacts = new Contact[5];
ArrayNum = 0;
}
And what I want to do is enter a name of someone on the contacts list and if they are found on their list return their index like so:
System.out.println("Who do you want to remove?");
String name = input.nextLine();
for(Contact c: contacts){
if(c.getName().equals(name)){
//Get the index here
}
}
I tried researching this but no answer or guide seems to be very clear on this so I'm hoping that someone can explain this for me.
Thank you for looking
for(int index = 0; index < contacts.length; index++) {
if(contacts[index].getName().equals(name)) {
// use the index here
}
}
I don't think this code snippet needs any further explanation.
Use a for loop that uses a counter instead.
for(int i = 0; i < contacts.length, i++) {
if(contacts[i].getName().equals(name)) {
// do something with the index, i
}
}
You could use a counter
System.out.println("Who do you want to remove?");
String name = input.nextLine();
int remove_index = -1;
for(int i=0; i<contacts.length; i++){
Contact c = contacts[i];
if(c.getName().equals(name)){
remove_index =i;
}
}
Another alternative that may be helpful down the line is to use an ArrayList<Contact> instead of a c-style array (Contact[]). This class might add more handling complexity than it's worth, but it includes a lot of useful extra methods, including an int indexOf(<T> object) where <T> is the type you specified in your declaration (i.e., Contact for ArrayList<Contact> contacts).
Bad idea! You can't do that seriously, if you have an array. Of course you can set an index to null, but then you have to search for a null entry to reference a new contact within the array.
Note: you have an Iterator while writing
for(Contact c: contacts){...
So one option is to iterate by index, but it's a bad option. Better make your Array a Set. Then you might write:
for (Iterator<Contact> iter = mySet.iterator();iter.hasNext();) {
final Contact next = iter.next();
if(next.getName() == "NAME") {
iter.remove();
break;
}
Always use Iterator.remove()! Otherwise you will get Exceptions earlier than you wish :D
This method removes duplicate objects from a list that have the same address field. it works for me at the moment. But I am upgrading my application and I am expecting my ArrayLists to get bigger. (200+ objects)
I am worried it might be too slow for comparing 200 records for example, since It is O(n2)
How can I improve it.
public static ArrayList<Place> removeDuplicates(ArrayList<Place> masterList) {
ArrayList<Place> tempList = new ArrayList<Place>(masterList);
for (int i = 0; i < tempList.size(); i++) {
String address = tempList.get(i).getAddress();
for (int j = 0; j < tempList.size(); j++) {
String address2 = tempList.get(j).getAddress();
if (address.equalsIgnoreCase(address2) && i != j) {
tempList.remove(tempList.get(j));
}
}
}
return tempList;
}
edit
Thanks all for the unanimous answers. I have a finasl question. What goes in the hashcode and equals methods when I over ride them?
Make sure the instances produce a good hashcode and use HashSet or LinkedHashSet (if you want to preserve order):
return new ArrayList<Place>(new LinkedHashSet<Place>(masterList));
The best you can do is overwriting the hashcode and equals methods and generate a Set from your list.
In this way is java that takse care of removing duplicate elements in the list, and not you.
public static ArrayList<Place> removeDuplicates(ArrayList<Place> masterList) {
Set<Place> temp = new HashSet<Place>();
for(Place place : masterList) {
if(!temp.add(place)) {
masterList.remove(place);
}
}
return masterList;
}
Your masterlist of places
List<Place> masterList = new ArrayList<Place>();
masterList.add(new Place());
masterList.add(new Place());
masterList.add(new Place());
Removing the duplicates by adding to set "s"
Set<Place> s = new TreeSet<Place>(new Comparator<Place>() {
#Override
public int compare(Place o1, Place o2) {
return o1.getAddress().compareToIgnoreCase(o2.getAddress());
}
});
s.addAll(masterList);
Printing your result
List<Object> res = Arrays.asList(s.toArray());
for (Object object : res) {
Place place = (Place)object;
}
If you have equals and hashcode defined for Place object, just create HashSet from arraylist, and then create arraylist from set.
I have an ArrayList of an bean class consisting five fields as
Java Bean -- MyShares
fileName
filePath
fileSize
isShared
Creator
I Want to make a ArrayList of filePath from this arraylist of bean class
I don't have vast knowledge on Java collections. So what will be the shortest logic for this.
The present logic which I have implemented is below, Now I want an optimized Logic to do so
ArrayList<Myshares> fileDetails = new ReadSDCard().getSdCardFiles();
if (!fileDetails.isEmpty()) {
for (int i = 0; i < fileDetails.size(); i++) {
CommonUtilities.filePaths.add(fileDetails.get(i).getPath());
}
}
if (!CommonUtilities.filePaths.isEmpty()) {
for (int i = 0; i < CommonUtilities.filePaths.size(); i++) {
Log.d(Integer.toString(i), CommonUtilities.filePaths.get(i));
}
}
CommonUtilities.filePaths is my static ArrayList in which I want to store the file paths
What you doing is fine but u need to check whether path is null before inserting in CommonUtilities.filePaths. You can also use a iterator instead of for loop.
You can may be avoid two for loops and just do the following:
ArrayList<Myshares> fileDetails = new ReadSDCard().getSdCardFiles();
int j=0;
if (!fileDetails.isEmpty()) {
for (int i = 0; i < fileDetails.size(); i++) {
if(fileDetails.get(i).getPath()!=null){
CommonUtilities.filePaths.add(fileDetails.get(i).getPath());
Log.d(Integer.toString(j), CommonUtilities.filePaths.get(j));
j++;
}
}
}
Im struggeling to understand why you would have two loops. One that loops through the fileDetails collection and add the paths to a new collection, and then you loop through the new collection for logging. Do these two steps in the same loop:
if (!fileDetails.isEmpty()) {
for (int i = 0; i < fileDetails.size(); i++) {
CommonUtilities.filePaths.add(fileDetails.get(i).getPath());
Log.d(Integer.toString(i), fileDetails.get(i).getPath());
}
}
Other then that I cannot see how this could be optimated since it's impossible to add the paths to a new array without looping through the one with fileDetails. This logic will run in O(n) time
Why to use CommonUtilities again to get the file paths ? We can log the path at the same instance while iterating
ArrayList<Myshares> fileDetails = new ReadSDCard().getSdCardFiles();
if (!fileDetails.isEmpty()) {
for (int i = 0,n=fileDetails.size(); i < n; i++) {
CommonUtilities.filePaths.add(fileDetails.get(i).getPath());
Log.d(Integer.toString(i),fileDetails.get(i).getPath());
}
}
Please see the construct :
for (int i = 0,n=fileDetails.size(); i < n; i++)
We can use this , provided , we are sure that fileDetails.size() will return same result (list is not being modified).
This will save us from calling fileDetails.size() each time
considering there is a structure as described in http://prohost.lt/stack/q.png
In the main arrayList we have n elements(sub arrayLists) (as for image we can consider n=3).
How to make a dynamic loop thru all sub arrayLists so as to get:
sarraylist1.get(0), sarrayList2.get(0), .. sarraylistN.get(0)
In case n=3 it would be
for(sarraylist1){
for( sarraylist2){
for(sarraylist3){
element from every list
}
}
}
Maybe I misunderstood what you were asking, but would something as simple as this not work?
List<List> lists = new ArrayList<List>();
for(List l : lists){
for(List subl: l)
Object o = subl.get(0);
}
Based on your scheme of the image, you can also do it with the "for while loop":
for (int mainArrayElements = 0; mainArrayElements < listOfLists.size(); mainArrayElements++) {
List arraysInMain = ((List)listOfLists.get(mainArrayElements));
for (int subArrayElements = 0; subArrayElements < arraysInMain.size(); subArrayElements++) {
List deepArray = ((List)listOfLists.get(subArrayElements));
for (int innerArrayElements = 0; innerArrayElements < deepArray.size() ; innerArrayElements++) {
System.out.println(deepArray.get(innerArrayElements));
}
}
}
But as mentioned before, recursion would be a really great combo to knock out the problem :).
Best regards.
If I understood correctly, you have one List containing n Lists for which you want to get the first, second and so on, element of each list. This code does that.
for (int i = 0; i < highestSizeOfChildrenList; i++) {
List<Object> lstOfItemInChild = new Arraylist<Object>();
for (List childList : mainList) {
if (i < childList.size()) {
lstOfItemInChild.add(childList.get(i));
}
}
// lstOfItemInChild now contains all the element i of the sub arrays
}
You will need to know the size of the biggest subList to get all the elements of that list, that is what highestSizeOfChildrenList represents.
After watching your comment I suggest you to use recursive approach to solve your problem.
public void recursiveCall(ArrayList list)
{
for ( Object obj : list)
{
if (obj instanceOf ArrayList)
{
recursiveCall((ArrayList)obj);
}
else
{
System.out.print(obj);
}
}
}